简介:本文深入解析FastAPI框架中认证与授权的核心机制,涵盖JWT、OAuth2.0、依赖注入等关键技术,提供安全架构设计指南与实战代码示例。
在FastAPI应用开发中,认证(Authentication)与授权(Authorization)是构建安全API的两大基石。认证解决”用户是谁”的问题,通过验证用户身份凭证(如密码、令牌)确认其合法性;授权则解决”用户能做什么”的问题,基于角色或权限控制资源访问。
FastAPI通过依赖注入系统(Dependency Injection)和安全模块(Security Utilities)提供了灵活的认证授权支持。其核心优势在于:
典型认证流程包含三个阶段:
JSON Web Token(JWT)是FastAPI中最常用的认证方案,其结构由头部(Header)、载荷(Payload)和签名(Signature)三部分组成。
from fastapi import Depends, FastAPI, HTTPExceptionfrom fastapi.security import OAuth2PasswordBearerfrom jose import JWTError, jwtfrom datetime import datetime, timedelta# 配置参数SECRET_KEY = "your-secret-key"ALGORITHM = "HS256"ACCESS_TOKEN_EXPIRE_MINUTES = 30app = FastAPI()oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")def create_access_token(data: dict, expires_delta: timedelta = None):to_encode = data.copy()if expires_delta:expire = datetime.utcnow() + expires_deltaelse:expire = datetime.utcnow() + timedelta(minutes=15)to_encode.update({"exp": expire})encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)return encoded_jwtasync def get_current_user(token: str = Depends(oauth2_scheme)):credentials_exception = HTTPException(status_code=401,detail="Could not validate credentials",headers={"WWW-Authenticate": "Bearer"},)try:payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])username: str = payload.get("sub")if username is None:raise credentials_exceptionexcept JWTError:raise credentials_exceptionreturn {"username": username} # 实际应返回用户对象
exp声明设置有效期,结合refresh token机制实现无缝续期FastAPI原生支持OAuth2.0授权框架,提供四种授权模式:
from fastapi.security import OAuth2PasswordRequestForm@app.post("/token")async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):# 实际应查询数据库验证用户if not form_data.username or not form_data.password:raise HTTPException(status_code=401, detail="Incorrect username or password")access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)access_token = create_access_token(data={"sub": form_data.username},expires_delta=access_token_expires)return {"access_token": access_token, "token_type": "bearer"}
需配合授权服务器(如Keycloak、Auth0)使用:
from fastapi import Requestfrom fastapi.security import OAuth2AuthorizationCodeBeareroauth2_code = OAuth2AuthorizationCodeBearer(tokenUrl="https://auth-server.com/token",scopes={"read": "Read items", "write": "Write items"})@app.get("/callback")async def callback(request: Request, code: str = None):# 使用code向授权服务器请求tokenpass
FastAPI通过依赖注入系统实现灵活的权限控制,典型实现方式:
from enum import Enumclass Role(str, Enum):admin = "admin"user = "user"guest = "guest"def get_current_active_user(current_user: dict = Depends(get_current_user),required_role: Role = Depends()):if current_user["role"] != required_role:raise HTTPException(status_code=403, detail="Operation not permitted")return current_user
@app.get("/admin/secret")async def admin_only(current_user: dict = Depends(get_current_active_user(Role.admin))):return {"secret": "42"}
uvicorn --ssl-keyfile --ssl-certfile启用TLSSecretStr类型处理密码字段速率限制:集成slowapi防止暴力破解
SameSite=Lax属性CORS配置:
from fastapi.middleware.cors import CORSMiddlewareapp.add_middleware(CORSMiddleware,allow_origins=["*"], # 生产环境应指定具体域名allow_credentials=True,allow_methods=["*"],allow_headers=["*"],)
多认证方案共存:
from fastapi.security import APIKeyHeaderapi_key_header = APIKeyHeader(name="X-API-Key")async def get_api_key(api_key: str = Depends(api_key_header)):if api_key != "secret-key":raise HTTPException(status_code=403, detail="Invalid API Key")return api_key@app.get("/protected")async def protected_route(api_key: str = Depends(get_api_key),token: str = Depends(oauth2_scheme)):return {"message": "Multi-factor authenticated"}
asyncpg)fastapi-jwt-auth:简化JWT操作
通过系统掌握上述技术方案,开发者可以构建出既安全又灵活的FastAPI认证授权体系。实际项目中,建议结合具体业务需求进行方案选型,并定期进行安全审计和渗透测试,确保API的安全性符合行业标准和法规要求。