0%

FastAPI自学教程(38) - 简单OAuth2密码与Bearer验证实现

1.基础用法

1
2
3
4
5
6
7
8
9
from fastapi import Depends, FastAPI, HTTPException
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm

app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

@app.get("/items/")
async def read_items(token: str = Depends(oauth2_scheme)):
return {"token": token}
  • 使用 OAuth2PasswordBearer 创建OAuth2密码流认证方案,自动从请求头提取Bearer Token
  • tokenUrl="token" 指定客户端获取令牌的端点路径,需与登录路由路径一致
  • 未携带有效Token的请求自动返回401错误,包含无效Token返回403错误

流程图:

graph TD
    A[客户端请求] --> B{Authorization头存在?}
    B -->|是| C[提取Bearer Token]
    B -->|否| D[返回401错误]
    C --> E[验证Token有效性]
    E -->|有效| F[执行路径操作]
    E -->|无效| G[返回403错误]

2.带类型的认证参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pydantic import BaseModel

class User(BaseModel):
username: str
disabled: bool = False

async def validate_credentials(form_data: OAuth2PasswordRequestForm = Depends()):
user = get_user(form_data.username)
if not verify_password(form_data.password, user.hashed_password):
raise HTTPException(400, "密码错误")
return user

@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
user = await validate_credentials(form_data)
return {"access_token": user.username, "token_type": "bearer"}
  • OAuth2PasswordRequestForm 强制要求表单字段命名为username/password
  • 添加Pydantic模型类型注解后自动实现:
    • 请求解析:自动转换表单数据为Python对象
    • 数据验证:检查用户状态与密码哈希匹配性
    • 错误处理:自动生成标准错误响应格式

3.多层级依赖验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
async def get_current_user(token: str = Depends(oauth2_scheme)):
user = decode_token(token)
if user.disabled:
raise HTTPException(400, "用户未激活")
return user

async def check_admin(user: User = Depends(get_current_user)):
if not user.is_admin:
raise HTTPException(403, "权限不足")
return user

@app.get("/admin")
async def admin_panel(admin: User = Depends(check_admin)):
return {"status": "管理员权限认证通过"}
  • 支持构建多层级验证链(用户存在性→激活状态→权限等级)
  • 每个依赖项可复用,避免重复验证逻辑
  • 错误响应自动传递,中断后续验证流程

4.生产环境注意事项

  1. 密码存储:使用 passlib 库的Bcrypt算法哈希密码,禁止明文存储
  2. 令牌安全:采用JWT签名算法(HS256/RS256),设置合理有效期
  3. 传输安全:必须启用HTTPS防止中间人攻击
  4. 速率限制:对 /token 端点实施请求频率控制
  5. 日志审计:记录登录失败事件和可疑Token使用情况

测试命令示例:

1
2
3
4
5
# 获取访问令牌
curl -X POST -d "username=admin&password=secret" http://localhost:8000/token

# 访问受保护端点
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:8000/items/