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

Django+React对接TrueLayer API时,HttpOnly Cookie存储的refresh_token无法获取导致无法刷新access_token的问题求助

Django+React对接TrueLayer API时,HttpOnly Cookie存储的refresh_token无法获取导致无法刷新access_token的问题求助

我目前用React写前端、Django做后端,对接TrueLayer的开放银行API,已经搞定了第一步的认证流程,但在实现用refresh_token刷新access_token的时候遇到了麻烦。

之前查资料说refresh_token要存在HttpOnly Cookie里才安全,所以我在TrueLayer回调接口里这么写的:

def truelayer_callback(request):
    code = request.GET.get('code')
    token_data = {
        "grant_type": "authorization_code",
        "client_id": settings.TRUELAYER_CLIENT_ID,
        "client_secret": settings.TRUELAYER_CLIENT_SECRET,
        "redirect_uri": REDIRECT_URI,
        "code": code,
    }
    try:
        data = requests.post(TOKEN_URL, data=token_data).json()
        access_token = data.get('access_token')
        refresh_token = data.get('refresh_token')
        if access_token:
            query_params = urlencode({'token' : access_token})
            response = HttpResponseRedirect(f'{FRONTEND_URL}?{query_params}')
            response.set_cookie(key='refresh_token', value=refresh_token, httponly=True, secure=False, samesite='Lax')
            return response
        return HttpResponseRedirect(f'{FRONTEND_URL}?error=No access token received')
    except Exception as e:
        return HttpResponseRedirect(f'{FRONTEND_URL}?error={str(e)}')

这里我把refresh_token设置到了响应的Cookie里,但之后调用刷新接口的时候,死活拿不到这个Cookie:

def check_refresh_cookie(request):
    refresh_token = request.COOKIES.get("refresh_token") # 这里拿到的是None!
    token_data = {
        "grant_type": "refresh_token",
        "client_id": settings.TRUELAYER_CLIENT_ID,
        "client_secret": settings.TRUELAYER_CLIENT_SECRET,
        "refresh_token": refresh_token,
    }
    try:
        response =  requests.post(TOKEN_URL, data=token_data)
        return JsonResponse({'access_token' : response.json()})
    except Exception as e:
        return  HttpResponseRedirect(f'{FRONTEND_URL}?error={str(e)}')

现在我有点懵,不知道怎么才能既安全存储refresh_token,又能正常拿到它来刷新access_token。前端那边就是个按钮绑定了点击事件,暂时没什么复杂逻辑。

补充说明:核心问题就是我在回调接口里设置了Cookie,但调用check_refresh_cookie时refresh_token是None,完全不符合预期。


嘿,我来帮你捋捋这个问题!HttpOnly Cookie拿不到的情况,大概率是跨域配置或者Cookie属性的问题,咱们一步步排查:

1. 先搞定跨域请求的Cookie携带问题

如果你的React前端和Django后端是跨域的,那前端发起请求时必须明确告诉浏览器要携带Cookie,不然浏览器会自动忽略。举个例子:

  • 用fetch的话:
fetch('http://你的Django后端地址/check_refresh_cookie', {
  method: 'POST',
  credentials: 'include'
})
  • 用axios的话:
axios.post('http://你的Django后端地址/check_refresh_cookie', {}, {
  withCredentials: true
})

同时Django这边要允许跨域携带Cookie,如果你用的是django-cors-headers,得在settings.py里加这些配置:

CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = [
    'http://你的React前端地址'  # 必须写具体地址,不能用*
]

2. 检查Cookie的属性配置

你设置Cookie时用了secure=False,如果生产环境是HTTPS的话,这个属性会导致Cookie不被存储;反过来如果后端是HTTPS、前端是HTTP,也会有问题。另外SameSite=Lax在某些跨域POST请求场景下,浏览器可能不会发送Cookie,你可以根据环境调整:

response.set_cookie(
    key='refresh_token',
    value=refresh_token,
    httponly=True,
    secure=not settings.DEBUG,  # 本地调试关secure,生产环境开
    samesite='None' if not settings.DEBUG else 'Lax',  # 生产环境要SameSite=None配合secure=True
    domain='你的后端域名',  # 如果前后端域名不同,必须显式设置这个值
    max_age=3600*24*7  # 给Cookie设个过期时间,别永久有效
)

3. 先确认Cookie有没有被存下来

打开浏览器开发者工具的Application标签(Chrome),看看Cookies里有没有refresh_token这个键:

  • 如果没有,说明回调接口的Cookie设置有问题,比如域名不匹配、secure属性冲突;
  • 如果有,但调用刷新接口时没传,那就是跨域请求的credentials配置没做好。

4. 排除CSRF的干扰

如果你的刷新接口是POST请求,Django默认会检查CSRF Token,没带的话请求会被拒绝,也可能间接导致Cookie读取异常。可以先给接口加@csrf_exempt装饰器临时关闭验证,确认是不是这个原因:

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def check_refresh_cookie(request):
    # 原代码不变

按这几个步骤排查,应该能找到问题所在!

备注:内容来源于stack exchange,提问作者Leo El

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 10:53:03