FastAPI(59)- 详解使用 OAuth2PasswordBearer + JWT 认证(上)

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: FastAPI(59)- 详解使用 OAuth2PasswordBearer + JWT 认证(上)

JWT


  • JSON Web Tokens
  • 它是一个将 JSON 对象编码为密集且没有空格的长字符串的标准
  • 使用 JWT token 和安全密码 hash 使应用程序真正安全

 

JWT 小栗子

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

  • 它还没有加密,因此任何人都可以从该字符串中恢复信息
  • 但是已经加签了,因此,当收到发出的 token 时,可以验证是否实际发出了它
  • 创建一个有效期为 1 周的 token,然后当用户第二天带着 token 回来时,知道该用户仍然登录到系统中
  • 一周后,令牌将过期,用户将无法获得授权,必须重新登录以获取新的 token
  • 如果用户(或第三方)试图修改 token 以更改过期时间,将能够发现它,因为签名不匹配

 

前提

需要安装 python-jose 来在 Python 中生成和验证 JWT token

pip install python-jose

pip install cryptography

 

JWT 流程


  • 前端登录提交用户名、密码
  • 后端拿到用户名、密码进行验证,如果没问题,则返回 token
  • 前端访问需要认证的 url 时携带 token
  • 后端拿到 token 进行验证
  • 验证通过返回用户信息及访问的 url 信息


image.png


hash 密码


前提

  • 数据库存储的密码不能是明文的,需要加密
  • PassLib 是一个用于处理哈希密码的包
  • 推荐的算法是 「Bcrypt

pip install passlib

pip install bcrypt

 

包含的功能

  • hash 密码
  • 验证 hash 密码是否一致
  • 通过用户名、密码验证用户

 

hash 密码

# 导入 CryptContext
from passlib.context import CryptContext
pwd_context = CryptContext(schemes=['bcrypt'], deprecated="auto")
# 密码加密
def hash_password(password: str) -> str:
    return pwd_context.hash(password)


验证 hash 密码是否一致

# 验证密码

def verify_password(plain_password, hashed_password):

   return pwd_context.verify(plain_password, hashed_password)

 

通过用户名、密码验证用户

# 模拟从数据库中根据用户名查找用户
def get_user(db, username: str):
    if username in db:
        user_dict = db[username]
        return UserInDB(**user_dict)
# 根据用户名、密码来验证用户
def authenticate_user(db, username: str, password: str):
    # 1、通过用户名模拟去数据库查找用户
    user = get_user(db, username)
    if not user:
        # 2、用户不存在
        return False
    if not verify_password(password, user.hashed_password):
        # 3、密码验证失败
        return False
    # 4、验证通过,返回用户信息
    return user


处理 JWT token


生成用于签名 JWT token 的随机密钥

在命令行敲

> openssl rand -hex 32

dc393487a84ddf9da61fe0180ef295cf0642ecbc5d678a1589ef2e26b35fce9c

 

常量池

方便后续复用

# 常量池
# 通过 openssl rand -hex 32 生成的随机密钥
SECRET_KEY = "dc393487a84ddf9da61fe0180ef295cf0642ecbc5d678a1589ef2e26b35fce9c"
# 加密算法
ALGORITHM = "HS256"
# 过期时间,分钟
ACCESS_TOKEN_EXPIRE_MINUTES = 30


创建生成 JWT token 需要用的 Pydantic Model

其实不创建也没事,但这里为了规范和数据校验功能,还是建吧

# 返回给客户端的 Token Model
class Token(BaseModel):
    access_token: str
    token_type: str
class TokenData(BaseModel):
    username: Optional[str] = None


生成 JWT token

# 导入 JWT 相关库
from jose import JWTError, jwt
# 用户名、密码验证成功后,生成 token
def create_access_token(
        data: dict,
        expires_delta: Optional[timedelta] = None):
    to_encode = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + expires_delta
    else:
        expire = datetime.utcnow() + timedelta(minutes=15)
    to_encode.update({"exp": expire})
    # 加密
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt


修改 get_current_user


获取 token 后解码并获取用户

# 导入 JWT 相关库
from jose import JWTError, jwt
# 根据当前用户的 token 获取用户,token 已失效则返回错误码
async def get_current_user(token: str = Depends(oauth2_scheme)):
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )
    try:
        # 1、解码收到的 token
        payload = jwt.decode(token, SECRET_KEY, algorithms=ALGORITHM)
        # 2、拿到 username
        username: str = payload.get("sub")
        if not username:
            # 3、若 token 失效,则返回错误码
            raise credentials_exception
        token_data = TokenData(username=username)
    except JWTError:
        raise credentials_exception
    # 4、获取用户
    user = get_user(fake_users_db, username=token_data.username)
    if not user:
        raise credentials_exception
    # 5、返回用户
    return user
相关文章
|
7月前
|
SQL Java 测试技术
在Spring boot中 使用JWT和过滤器实现登录认证
在Spring boot中 使用JWT和过滤器实现登录认证
343 0
|
5月前
|
JSON 安全 数据安全/隐私保护
Python认证新风尚:OAuth遇上JWT,安全界的时尚Icon👗
【10月更文挑战第2天】在当今互联网世界中,数据安全与隐私保护日益重要。Python 作为广泛应用于 Web 开发的语言,其认证机制也不断进化。OAuth 2.0 和 JSON Web Tokens (JWT) 成为当前最热门的安全认证方案,不仅保障数据安全传输,还简化了用户认证流程。本文将介绍 Python 如何结合 OAuth 2.0 和 JWT 打造安全高效的认证体系。
54 3
|
2月前
|
XML JavaScript Java
SpringBoot集成Shiro权限+Jwt认证
本文主要描述如何快速基于SpringBoot 2.5.X版本集成Shiro+JWT框架,让大家快速实现无状态登陆和接口权限认证主体框架,具体业务细节未实现,大家按照实际项目补充。
103 11
|
4月前
|
JSON 安全 算法
Spring Boot 应用如何实现 JWT 认证?
Spring Boot 应用如何实现 JWT 认证?
112 8
|
4月前
|
JSON 安全 数据安全/隐私保护
Python认证新风尚:OAuth遇上JWT,安全界的时尚Icon👗
在当今互联网世界中,数据安全和隐私保护至关重要。Python 作为 Web 开发的主流语言,其认证机制也在不断进步。OAuth 2.0 和 JSON Web Tokens (JWT) 是当前最热门的安全认证方案,不仅保障数据安全传输,还简化用户认证流程。本文介绍如何在 Python 中结合 OAuth 2.0 和 JWT,打造一套既安全又高效的认证体系。通过 Flask-HTTPAuth 和 PyJWT 等库,实现授权和验证功能,确保每次请求的安全性和便捷性。
64 3
|
4月前
|
JSON 算法 安全
JWT Bearer 认证在 .NET Core 中的应用
【10月更文挑战第30天】JWT(JSON Web Token)是一种开放标准,用于在各方之间安全传输信息。它由头部、载荷和签名三部分组成,用于在用户和服务器之间传递声明。JWT Bearer 认证是一种基于令牌的认证方式,客户端在请求头中包含 JWT 令牌,服务器验证令牌的有效性后授权用户访问资源。在 .NET Core 中,通过安装 `Microsoft.AspNetCore.Authentication.JwtBearer` 包并配置认证服务,可以实现 JWT Bearer 认证。具体步骤包括安装 NuGet 包、配置认证服务、启用认证中间件、生成 JWT 令牌以及在控制器中使用认证信息
189 2
|
6月前
|
安全 Java 数据安全/隐私保护
|
6月前
|
JSON 安全 数据安全/隐私保护
Python 安全性大揭秘:OAuth 与 JWT,不只是认证,更是信任的传递
【9月更文挑战第4天】在数字化时代,确保应用安全至关重要。Python 作为广泛使用的编程语言,提供了强大的安全认证工具,如 OAuth 和 JWT。OAuth 是一种授权框架,允许第三方应用在有限权限下访问用户资源;JWT 则是一种自包含的数据传输格式,用于安全地传递声明。通过合理配置和使用这些技术,可以有效提升应用安全性,保障用户数据安全。正确管理和定期更新密钥、严格测试 JWT 的生成与验证等最佳实践,对于构建安全可靠的应用至关重要。不断学习新威胁,是维护应用安全的永恒课题。
71 2
|
7月前
|
JSON 安全 数据安全/隐私保护
Python 安全性大揭秘:OAuth 与 JWT,不只是认证,更是信任的传递
【8月更文挑战第6天】在数字化时代,Python 通过 OAuth 和 JWT 筑牢应用安全防线。OAuth 是一种授权框架,允许第三方应用在用户授权下安全访问资源;JWT 则是一种自包含的声明传输格式,确保通信安全。两者结合使用,能有效进行身份验证及授权管理。然而,密钥管理和 JWT 有效期设置等仍是挑战,需谨慎处理以保障整体安全性。正确配置这些工具和技术,可为用户提供既安全又便捷的服务体验。
60 7
|
7月前
|
JSON 人工智能 算法
Golang 搭建 WebSocket 应用(四) - jwt 认证
Golang 搭建 WebSocket 应用(四) - jwt 认证
90 0