我有一个在本地工作的 Django 项目,可以登录管理门户。将项目部署到我们的开发环境后,可以查看不需要 CSRF 身份验证的页面,但管理门户在尝试登录时返回 CSRF 令牌错误。
收到错误:
CSRF cookie not set
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 的文档进行操作,并将
CSRF_TRUSTED_ORIGINS = ['https://*.myapp.com']
添加到设置中,但问题仍然存在。
我还尝试将
CSRF_COOKIE_DOMAIN
设置设置为 .myapp.com
或 .dev.myapp.com
,但仍然看到同样的问题。
我还看到人们提到
django.template.context_processors.csrf
选项添加到模板 context_processors 并尝试过,但这也没有效果。
查看对 /admin/login 视图的请求时,包含
csrfmiddlewaretoken
,但浏览器中未进行任何设置。
我缺少其他设置吗?
附注 部署是在 nginx 后面使用 uwsgi 运行的,但由于页面仍然正常服务,我(可能是错误的)假设问题不在那里。
也许您可以使
SESSION_COOKIE_SECURE
和 CSRF_COOKIE_SECURE
标志匹配。您已设置 CSRF_COOKIE_SECURE = False
。如果 SESSION_COOKIE_SECURE
为 True,则可能是导致问题的原因。您应该在开发期间将这两个标志设置为 False,或者在生产 HTTPS 环境中将它们都设置为 True。
SESSION_COOKIE_SECURE = False
CSRF_COOKIE_SECURE = False
对于 CSRF Cookie 域,当您移动到新的子域时,开头的句点
.
至关重要。这可确保包含所有子域。
CSRF_COOKIE_DOMAIN = '.myapp.com'
并且,确保您的 NGINX 配置不会因某种原因删除“Cookie”标头可能会有所帮助。 Django 中的 CSRF 令牌机制通过将会话 cookie 中存储的值与隐藏表单字段或 HTTP 标头中发送的值进行比较来工作。如果您的 NGINX 配置未正确转发 Cookie 标头,这可能会导致问题。