FastAPI跨域重定向时Cookie与Header无法传递的解决方法
跨域重定向(不同域名/IP)时,浏览器出于安全遵循同源策略,不会将源响应中的Cookie或自定义Header自动携带到目标域名的请求中。你当前的写法是给源域名设置Cookie,而目标域名属于另一个域,自然无法获取;自定义Header同理,浏览器重定向时不会保留这些Header。
以下是几种可行的解决方案:
方案1:通过URL参数传递令牌(适合临时场景)
如果只是要传递jwt_token,可以把令牌作为查询参数附加到重定向URL中,目标应用从URL参数中提取:
@router.post("/callback") async def sso_callback(request: Request): jwt_token = generate_token(request) # 将令牌作为查询参数添加到重定向URL redirect_url = f"http://192.168.10.1/app/callback?token={jwt_token}" return RedirectResponse(url=redirect_url, status_code=303)
目标应用处理时直接从查询参数token取值即可。注意:这种方式令牌会暴露在URL中,适合非敏感场景或短期令牌。
方案2:使用目标域名设置Cookie(需跨域支持)
如果必须用Cookie传递,需要确保Cookie是设置给目标域名的,同时满足跨域Cookie的条件:
- Cookie的
domain属性要设置为目标域名(或其公共父域,需确保两个域属于同一主域) - 开启
secure属性(如果使用HTTPS) - 设置
samesite="None"(跨域场景下必须)
修改代码如下:
@router.post("/callback") async def sso_callback(request: Request): jwt_token = generate_token(request) redirect_response = RedirectResponse(url="http://192.168.10.1/app/callback", status_code=303) # 针对目标域名设置Cookie,注意domain要匹配目标域 redirect_response.set_cookie( key="accessToken", value=jwt_token, httponly=True, domain="192.168.10.1", # 目标域名/IP samesite="None", secure=False, # 本地HTTP环境设为False,HTTPS环境设为True path="/" # 确保Cookie在目标应用的所有路径可用 ) return redirect_response
注意:如果两个域名不属于同一主域,这种方式可能受浏览器跨域Cookie限制,需要目标域名配合设置CORS允许凭证。
方案3:后端间直接传递令牌(推荐)
更安全可靠的方式是让两个应用的后端直接通信:
- 源应用(FastAPI)在
/callback接口处理完后,直接调用目标应用的后端接口,将jwt_token通过请求Header或请求体传递 - 目标应用验证令牌后,生成自己的会话Cookie或返回授权结果
- 源应用再重定向到目标应用的前端页面,此时用户已完成授权
示例代码(源应用):
import httpx @router.post("/callback") async def sso_callback(request: Request): jwt_token = generate_token(request) # 后端调用目标应用的验证接口,传递令牌 async with httpx.AsyncClient() as client: await client.post( "http://192.168.10.1/api/verify-token", headers={"Authorization": f"Bearer {jwt_token}"} ) # 重定向到目标应用前端 return RedirectResponse(url="http://192.168.10.1/app/callback", status_code=303)
这种方式避免了前端传递敏感令牌的风险,安全性更高。
关于自定义Header无法传递的补充
跨域重定向时,浏览器只会保留少数标准Header(如Location),自定义Header不会被携带到目标请求中。如果必须传递额外信息,优先采用上述URL参数或后端通信的方式。
内容的提问来源于stack exchange,提问作者user6552837
相关产品推荐
相关产品推荐

