FastAPI中应在何处存储会话级用户令牌/密钥?
FastAPI 会话级外部API Access Token 存储方案
结合你「仅会话周期有效、无需长期持久化、后续调用可快速获取」的需求,按实际部署场景选对应方案即可,完全不需要引入数据库:
方案1:服务端内存缓存(单实例部署首选,零额外依赖成本)
如果你是单进程/单容器部署FastAPI,没有多节点负载均衡:
- 先给每个访问的用户生成唯一的随机会话ID,写入用户端Cookie,必须给Cookie加上
HttpOnly、Secure、SameSite=Lax属性,防范XSS、CSRF风险 - 服务端维护一个带自动过期的内存缓存,以会话ID为key,外部API返回的access token为value,缓存过期时间和你拿到的access token有效期完全对齐,自动清理过期token即可
- 实现上不用自己写过期逻辑,直接用
cachetools.TTLCache就行,示例初始化代码:
from cachetools import TTLCache # 最多存10000个会话,默认过期时间和外部API token有效期对齐,比如3600秒 token_cache = TTLCache(maxsize=10000, ttl=3600)
- 后续流程:用户完成外部API认证拿到token后,直接执行
token_cache[session_id] = access_token存入;调用外部API时,从当前请求的Cookie里取session_id,直接从缓存里拿token即可,读取速度是微秒级,完全满足便捷获取的要求。
方案2:无状态签名Cookie(多实例部署轻量方案,无需服务端存储)
如果是多节点负载均衡部署,不想额外搭缓存服务,可以用签名Cookie存储:
- 拿到外部API返回的access token后,用只有你服务端知道的密钥,通过
itsdangerous.URLSafeTimedSerializer对token做签名加密,直接写入用户的HttpOnly Cookie,Cookie过期时间和token有效期对齐 - 后续请求进来时,直接从Cookie里读取出加密内容,验签解密后就能拿到原始token,全程不需要服务端存任何数据,单实例、多实例部署都兼容
注意:绝对不能把明文token直接存在Cookie里,也不能关闭Cookie的HttpOnly属性,否则会出现token篡改、泄露风险。
方案3:内存型缓存(多实例部署生产首选)
如果你的服务是生产环境多副本部署,并发量不低,直接部署一个关闭持久化的Redis实例即可:
- 以会话ID为key存access token,给每个key设置和token有效期一致的过期时间,不需要开RDB/AOF持久化,重启就清空,完全符合你不做长期存储的要求
- 所有服务节点都能访问这个Redis实例,不会出现请求切节点拿不到token的问题,性能足够支撑高并发场景。
避坑提醒
- 绝对不要把access token存在无用户隔离的全局变量里,否则会出现用户A拿到用户B的token、数据串号的严重安全问题
- 不要把token存在前端localStorage/sessionStorage里,XSS攻击会直接导致token泄露
- 不需要为了存储这个短生命周期的token引入关系型数据库,徒增维护成本。
内容的提问来源于stack exchange,提问作者oscar-lauth
相关产品推荐
相关产品推荐

