You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在FastApi中用Cookie存储JWT?请求排查登录代码问题

代码问题排查及修复方案

先梳理你代码里的核心问题,以及对应的修复方式:

1. 低级变量错误

设置refresh_token的Cookie时,你错误地传入了access_token的值:

# 错误写法
response.set_cookie(key="refresh_token",value=f"Bearer {access_token}", httponly=True)
# 正确写法
response.set_cookie(key="refresh_token",value=f"Bearer {refresh_token}", httponly=True)

这个错误会导致刷新令牌和访问令牌完全一致,完全失去了refresh_token的设计意义。

2. 响应返回方式不当

FastAPI路由中,你已经通过response.set_cookie操作了响应对象,不需要直接return response。直接返回JSON格式的业务响应即可,FastAPI会自动将设置好Cookie的响应返回给客户端:

# 替换原来的return response
return {"status": "success", "message": "登录成功"}

3. Cookie属性缺失(跨域场景关键)

如果你的React和FastAPI分属不同域名/端口,Cookie必须补充以下属性才能被浏览器正确携带:

  • secure=True:生产环境HTTPS下必须开启,确保Cookie仅通过加密连接传输(开发环境HTTP可设为False)
  • samesite="Lax":平衡跨域可用性和CSRF防护,适合大多数场景
  • max_age:明确设置Cookie有效期,比如access_token设15分钟,refresh_token设7天

4. 跨域配置缺失

必须在FastAPI中配置CORS中间件,允许携带凭证,否则浏览器会拦截Cookie:

from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://你的React地址:端口"],  # 替换为实际React地址
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

修复后的完整登录接口示例

@app.post("/login")
async def login(response: Response, data: OAuth2PasswordRequestForm = Depends()):
    username = data.username
    password = data.password

    user = await query_user(username)
    if not user:
        raise InvalidCredentialsException
    if not verify_password(password, user["password"]):
        raise InvalidCredentialsException

    access_token = accessToken.create(user)
    refresh_token = refreshToken.create(user)

    # 设置access_token Cookie
    response.set_cookie(
        key="access_token",
        value=f"Bearer {access_token}",
        httponly=True,
        secure=True,
        samesite="Lax",
        max_age=15*60  # 15分钟有效期
    )
    # 设置refresh_token Cookie
    response.set_cookie(
        key="refresh_token",
        value=f"Bearer {refresh_token}",
        httponly=True,
        secure=True,
        samesite="Lax",
        max_age=7*24*60*60  # 7天有效期
    )
    
    return {"message": "登录成功"}

React端配套设置

发送登录请求时,必须开启withCredentials,确保浏览器携带Cookie:

// Axios示例
axios.post('http://你的FastAPI地址/login', loginFormData, {
    withCredentials: true
})

额外检查点

  • 确认query_user能正确从MongoDB查询用户数据
  • 确认verify_password能正确校验密码哈希
  • 确认JWT生成函数的密钥、过期时间配置合理

内容的提问来源于stack exchange,提问作者Maximilián Mašek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 06:06:25