fastapi:用starlette-context实现存储当前登录用户,后续的任何业务代码直接读取,无需通过依赖注入传递
一,安装第三方库
库地址:
https://pypi.org/project/starlette-context/
安装:
$ pip install starlette-context
二,代码
1,登录后把用户信息保存到上下文中
from starlette_context.plugins import Plugin
import jwt
# --- 配置参数 ---
SECRET_KEY = "your-super-secret-key-change-me-1234567890" # 生产环境请使用安全的随机密钥
ALGORITHM = "HS256"
# 1. Define a custom plugin to extract the Authorization header
class AuthorizationPlugin(Plugin):
key = "authorization" # 写到context中时的key
has_header = True
async def process_request(self, request):
# Extract the token from incoming request headers
auth_header = request.headers.get("Authorization", "")
dict = {
"username": '',
"is_authenticated": False
}
if auth_header.startswith("Bearer "):
token = auth_header[7:]
print('token:',token)
# 解密 Token
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
print("in plugin username:", username)
if username:
# Store user info in context
dict["username"] = username
dict["is_authenticated"] = True
return dict
2, 应用middleware
# app/api/main.py
from fastapi import FastAPI
from starlette.middleware import Middleware
from app.api.middleware.api_sign import SignatureMiddleware
from app.api.middleware.authorization_plugin import AuthorizationPlugin
from app.api.v1 import tasktest, toke, users, account, products,asset
from app.core.exceptions import register_exception_handlers
from fastapi.staticfiles import StaticFiles
from starlette_context import context, plugins
from starlette_context.middleware import ContextMiddleware
from app.api.middleware.auth_middleware import AuthMiddleware
from starlette_context.middleware import ContextMiddleware
# 创建FastAPI应用,并传入 lifespan
api_app = FastAPI(title="我的API项目")
# 注册全局异常捕获
register_exception_handlers(api_app)
# 🚀 注册中间件
api_app.add_middleware(
ContextMiddleware,
plugins=(AuthorizationPlugin(),)
)
# 1. 挂载静态文件目录
# path="/static" 是浏览器访问静态文件的 URL 前缀
# directory="app/static" 是本地项目中的文件夹名称
# name="static" 是在 Jinja2 模板中引用时使用的别名
api_app.mount("/static", StaticFiles(directory="app/static"), name="static")
# 注册路由模块
api_app.include_router(account.router)
3, 从函数中获取用户信息: 注意没有传递request
def get_current_user_by_context():
auth = context.get("authorization")
print("authorization:", auth)
if auth is None:
username = ''
else:
is_authenticated = auth["is_authenticated"]
print("is_authenticated:", is_authenticated)
if is_authenticated == True:
username = auth["username"]
else:
username = ''
return {"username": username}
@router.get("/info2")
async def read_users_info2():
"""受保护的路由,只有携带有效 Token 才能访问"""
user = get_current_user_by_context()
return {"username": user["username"], "message": "如果username不为空,说明认证成功了!"}
三,测试效果:

浙公网安备 33010602011771号