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

部署到子域的Django Admin登录提示CSRF cookie未设置问题排查

Django子域部署Admin登录CSRF Cookie未设置问题排查与解决

本地Django项目的Admin后台登录功能正常,但部署到开发环境子域https://project.dev.myapp.com(生产域为https://project.myapp.com)后,无需CSRF认证的页面可正常访问,唯独Admin登录时返回CSRF cookie not set错误。查看/admin/login请求发现,表单已携带csrfmiddlewaretoken,但浏览器并未设置CSRF Cookie。

现有配置

Django settings.py 关键片段

ALLOWED_HOSTS = ['*']
CSRF_COOKIE_SECURE = False

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.gis',
    'django.contrib.messages',
    'django.contrib.sessions',
    'django.contrib.staticfiles',
    'django_object_actions',
]

MIDDLEWARE = (
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

已尝试的无效操作

  • 添加CSRF_TRUSTED_ORIGINS = ['https://*.myapp.com']
  • 设置CSRF_COOKIE_DOMAIN为.myapp.com或.dev.myapp.com
  • 向TEMPLATES的context_processors添加django.template.context_processors.csrf

Nginx相关配置

nginx.conf

user              nginx;
worker_processes  auto;

error_log  /dev/stderr warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format main '$realip_remote_addr [$time_local] "$request" '
                    '$status $body_bytes_sent $request_time '
                    '"$http_referer" "$http_user_agent" '
                    '"$http_x_amzn_trace_id" "$http_x_amz_cf_id"';

    access_log /dev/stdout main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    #maximum file size
    client_max_body_size 0;

    include /etc/nginx/conf.d/*.conf;
}

server.conf

upstream myapp {
  server 127.0.0.1:8000;
}

server {
  listen 7999 default_server;
  server_name $GENERAL_SUBDOMAIN.$GENERAL_DOMAIN;

  include /etc/nginx/conf.d/myapp.params;

  # Enable RealIP
  real_ip_header      X-Forwarded-For;
  real_ip_recursive   on;
  set_real_ip_from    0.0.0.0/0;
  uninitialized_variable_warn off;


  resolver 8.8.8.8;

  location /static/admin {
    uwsgi_pass myapp;
    include uwsgi_params;

    uwsgi_read_timeout 600;
    uwsgi_send_timeout 600;
    uwsgi_ignore_client_abort on;

    expires $static_expires;
  }

  location /static {
    root /app;
    expires $static_expires;
  }

  location / {
    uwsgi_pass myapp;
    include uwsgi_params;

    uwsgi_read_timeout 600;
    uwsgi_send_timeout 600;
    uwsgi_ignore_client_abort on;

    expires $static_expires;
  }
}
# vim: ft=nginx ts=2 sw=2

myapp.params

error_page 497 https://$best_http_host:$server_port$request_uri;

# vim: ft=nginx ts=2 sw=2

排查与解决步骤

  1. 修正HTTPS环境下的Cookie安全配置
    开发环境使用HTTPS,但CSRF_COOKIE_SECURE = False会导致浏览器拒绝保存Cookie(HTTPS页面默认要求Cookie标记为Secure)。修改settings.py:

    CSRF_COOKIE_SECURE = True
    SESSION_COOKIE_SECURE = True
    
  2. 传递正确的协议头给Django
    Django需要识别请求为HTTPS,否则不会发送Secure Cookie。在Nginx的location /和/static/admin块中添加:

    uwsgi_param X-Forwarded-Proto $scheme;
    

    同时在settings.py中开启代理SSL头识别:

    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
    
  3. 调整Cookie的SameSite属性
    现代浏览器对跨子域Cookie的SameSite属性有严格限制,添加以下配置到settings.py:

    CSRF_COOKIE_SAMESITE = 'Lax'
    SESSION_COOKIE_SAMESITE = 'Lax'
    

    若涉及跨域场景可设为'None',但必须配合Secure=True使用。

  4. 检查Nginx是否拦截Cookie头
    确认Nginx配置中没有过滤、修改响应头的规则,保证Django发送的CSRF Cookie能完整传递到浏览器。

  5. 清除浏览器缓存与Cookie
    之前的错误Cookie配置可能残留,手动清除后重新测试登录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 00:44:53