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

生产环境Django CSRF Token无法存入浏览器Cookie问题求助

问题排查与解决方案

核心原因分析

生产环境下CSRF Token未写入浏览器Cookie,主要和Azure Front Door的代理配置、iframe跨域Cookie限制以及Django的信任源配置有关——开发环境无代理且跨域限制宽松,因此未出现问题。

分步解决方案

1. 修正Azure Front Door代理配置

Azure Front Door默认可能过滤或修改响应头,需确保:

  • 允许传递Set-Cookie头,包含csrfmiddlewaretoken的Cookie必须能正常透传
  • 配置缓存规则,禁止缓存包含CSRF Token的页面(如base.html),避免Token过期或不更新
  • 确认Front Door与App Service之间使用HTTPS协议:CSRF_COOKIE_SECURE = True要求Cookie仅在HTTPS环境下传递,若代理层用HTTP,Cookie无法写入

2. 完善Django的CSRF配置

当前配置基础上补充以下项:

  • 添加CSRF_COOKIE_HTTPONLY = False:虽然你通过模板变量注入Token,但确保Cookie能被浏览器正常存储需关闭HTTPONLY限制
  • 配置CSRF_TRUSTED_ORIGINS,包含Front Door和App Service的域名:
    CSRF_TRUSTED_ORIGINS = [
        'https://你的FrontDoor域名.com',
        'https://你的AppService域名.azurewebsites.net'
    ]
    
    这是关键:Django必须信任代理过来的请求来源,否则不会生成并返回CSRF Cookie。

3. 优化AJAX请求逻辑

  • 替换模板变量注入Token的方式,改为从Cookie读取,更可靠:
    function getCookie(name) {
        let cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            const cookies = document.cookie.split(';');
            for (let i = 0; i < cookies.length; i++) {
                const cookie = cookies[i].trim();
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
    const csrf_token = getCookie('csrftoken');
    
  • 修复AJAX请求的参数冲突:代码同时写了type: 'GET'和method: 'POST',会导致请求方法混乱,删除type字段,保留method: 'POST'

4. 验证iframe跨域权限

Shopify iframe嵌入场景下,需确保页面响应头包含:

Permissions-Policy: interest-cohort=(), cross-origin-isolated=()

同时确认你的域名已添加到Shopify应用配置的有效重定向URL列表中,避免Shopify限制未授权域名的嵌入。

5. 调试Cookie写入过程

打开浏览器开发者工具排查:

  • 查看Network面板,加载base.html时的响应头是否存在Set-Cookie: csrftoken=xxx; Secure; SameSite=None; ...
  • 若无该响应头:检查CSRF_TRUSTED_ORIGINS配置是否正确,Django未生成Cookie
  • 有响应头但浏览器未存储:检查浏览器隐私设置(如第三方Cookie阻止)或插件是否拦截了跨域Cookie

临时替代方案(不建议长期使用)

若以上步骤暂时无法生效,可用@csrf_protect替代@csrf_exempt,同时手动强化Token验证:

from django.middleware.csrf import get_token
from django.http import JsonResponse

@csrf_protect
def your_view(request):
    if request.method == 'POST':
        token = request.headers.get('X-CSRFToken')
        if not token or token != get_token(request):
            return JsonResponse({'error': '无效的CSRF Token'}, status=403)
        # 业务逻辑代码
    return JsonResponse({'status': 'ok'})

内容的提问来源于stack exchange,提问作者Ross

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 14:22:05