FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,与 Python 3.6+ 类型提示一起使用。它旨在快速开发,同时易于学习和使用。在开发过程中,安全认证是保障 API 安全性的关键环节。本文将深入探讨 FastAPI 中的高效安全认证方法,帮助开发者轻松守护 API 之门,告别漏洞隐患。

一、FastAPI 安全认证概述

安全认证是确保 API 安全性的第一步。它涉及到用户身份的验证和权限的授权。在 FastAPI 中,常用的认证方法包括:

  • 基于密码的认证
  • 基于令牌的认证
  • 基于OAuth的认证
  • 基于JWT(JSON Web Tokens)的认证

以下将分别介绍这些认证方法。

二、基于密码的认证

基于密码的认证是传统的认证方式,它要求用户在登录时提供用户名和密码。以下是一个简单的基于密码的认证示例:

from fastapi import FastAPI, Depends, HTTPException, status from fastapi.security import HTTPBasic, HTTPBasicCredentials app = FastAPI() security = HTTPBasic() # 用户名和密码 fake_users_db = { "admin": "secret" } def authenticate_user(credentials: HTTPBasicCredentials = Depends(security)): user = fake_users_db.get(credentials.username) if not user or user != credentials.password: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect username or password", headers={"WWW-Authenticate": "Basic"}, ) return user @app.get("/items/") async def read_items(username: str = Depends(authenticate_user)): return {"message": "Welcome, " + username} 

三、基于令牌的认证

基于令牌的认证是一种无状态的认证方式,它使用令牌(如JWT)来验证用户身份。以下是一个简单的基于令牌的认证示例:

from fastapi import FastAPI, Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm app = FastAPI() oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") # 用户名和密码 fake_users_db = { "admin": { "username": "admin", "hashed_password": "fakehashedsecret" } } def authenticate_user(form_data: OAuth2PasswordRequestForm = Depends()): user = fake_users_db.get(form_data.username) if not user or not verify_password(form_data.password, user["hashed_password"]): raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect username or password", headers={"WWW-Authenticate": "Bearer"}, ) return user @app.post("/token/") async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()): user = authenticate_user(form_data) return {"access_token": user["username"], "token_type": "bearer"} @app.get("/items/") async def read_items(token: str = Depends(oauth2_scheme)): return {"message": "Welcome, " + token} 

四、基于OAuth的认证

基于OAuth的认证是一种授权机制,它允许第三方应用代表用户请求受保护的资源。以下是一个简单的基于OAuth的认证示例:

from fastapi import FastAPI, Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer app = FastAPI() oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") @app.post("/token/") async def login_for_access_token(username: str = Depends(oauth2_scheme)): # 假设这里进行了OAuth2认证 return {"access_token": "token", "token_type": "bearer"} @app.get("/items/") async def read_items(token: str = Depends(oauth2_scheme)): return {"message": "Welcome, " + token} 

五、基于JWT的认证

基于JWT的认证是一种常用的无状态认证方式,它使用JWT作为令牌。以下是一个简单的基于JWT的认证示例:

from fastapi import FastAPI, Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from jose import JWTError, jwt from datetime import datetime, timedelta SECRET_KEY = "your_secret_key" ALGORITHM = "HS256" app = FastAPI() oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") fake_users_db = { "admin": { "username": "admin", "hashed_password": "fakehashedsecret" } } def create_access_token(data: dict, expires_delta: 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 @app.post("/token/") async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()): user = authenticate_user(form_data) access_token_expires = timedelta(minutes=30) access_token = create_access_token( data={"sub": user["username"]}, expires_delta=access_token_expires ) return {"access_token": access_token, "token_type": "bearer"} @app.get("/items/") async def read_items(token: str = Depends(oauth2_scheme)): credentials_exception = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, 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_exception except JWTError: raise credentials_exception return {"message": "Welcome, " + username} 

六、总结

本文介绍了 FastAPI 中的几种常用认证方法,包括基于密码的认证、基于令牌的认证、基于OAuth的认证和基于JWT的认证。这些认证方法可以帮助开发者轻松守护 API 之门,确保 API 的安全性。在实际开发过程中,开发者可以根据具体需求选择合适的认证方法,并结合其他安全措施,如HTTPS、CSRF保护等,进一步提升 API 的安全性。