Django在使用HTTPS时CSRF验证无效。

65

我正在开发一个应用程序,其中前端是使用AngularJS API制作的,它向使用Django Rest Framework开发的后端API发送请求。

The frontend is on the domain: https://front.bluemix.net
And my backend is on the domain: https://back.bluemix.net

我在前端API向后端API发出请求时遇到了问题。错误信息如下:

Error: CSRF Failed: Referer checking failed - https://front.bluemix.net does not match any trusted origins.

我正在使用CORS,已经在Django后端API的settings.py中包含了以下代码:

ALLOWED_HOSTS = []

CORS_ALLOW_CREDENTIALS = True

CORS_ORIGIN_ALLOW_ALL = True

CORS_ALLOW_CREDENTIALS = True


CSRF_TRUSTED_ORIGINS = ['https://front.bluemix.net/']

CORS_REPLACE_HTTPS_REFERER = True

CSRF_COOKIE_DOMAIN = 'bluemix.net'

CORS_ORIGIN_WHITELIST = (
    'https://front.bluemix.net/',
    'front.bluemix.net',
    'bluemix.net',
)

有人知道如何解决这个问题吗?


你是否按照 https://github.com/ottoyiu/django-cors-headers/ 中的所有步骤进行操作了? - wilcus
是的,我做了!错误还是一样的... - ccr
也许你的 Django 版本不受支持。请尝试使用这个分支 https://github.com/zestedesavoir/django-cors-middleware - wilcus
这个回答解决了您的问题吗?[Forbidden (403) CSRF verification failed. Request aborted. Reason given for failure: Origin checking failed does not match any trusted origins](https://dev59.com/tlEG5IYBdhLWcg3wN29K) - dfrankow
8个回答

150

Django 4.0及更高版本

对于Django 4.0及以上版本,CSRF_TRUSTED_ORIGINS必须包括协议和主机名,例如:

CSRF_TRUSTED_ORIGINS = ['https://front.bluemix.net']

Django 3.2及以下版本

对于Django 3.2及以下版本,CSRF_TRUSTED_ORIGINS必须只包含主机名,而不包括方案:(详情请见)

CSRF_TRUSTED_ORIGINS = ['front.bluemix.net']

你可能还需要在ALLOWED_HOSTS中放置一些内容...


谢谢,问题出在CSRF_TRUSTED_ORIGINS上。现在它像魔法一样工作了 :) - ccr
谢谢你,我的朋友。我也遇到了同样的问题,现在已经解决了!! - WitnessTruth
2
公共实用程序:您可能需要指定 Web 服务器端口,因此请使用 CSRF_TRUSTED_ORIGINS = ['localhost:8080'] - Igor de Lorenzi
7
请注意,Django 4.0发生了变化。现在需要指定方案(scheme)。https://docs.djangoproject.com/en/4.0/releases/4.0/#csrf-trusted-origins-changes-4-0 - Tom Wojcik
1
@java-addict301,是的,尾随斜杠会导致CSRF失败。 - tbm
显示剩余5条评论

14

11
我也遇到了这个问题。请确保域名不包含尾部斜杠。应该使用:
CSRF_TRUSTED_ORIGINS = ['https://front.bluemix.net/']

将其更改为

CSRF_TRUSTED_ORIGINS = ['https://front.bluemix.net']

2
非常感谢。 这个愚蠢的错误浪费了我们很多时间。 - Arkadiusz Mazur
这个建议真是太宝贵了。 - ZuBB

9

如果您将CORS_ORIGIN_ALLOW_ALL设置为True,则不需要再设置CORS_ORIGIN_WHITELIST变量,因为您已经允许了每个主机。

我的问题的解决方案-它可能有助于某人

我们遇到的问题很奇怪,我们有一个客户端应用程序使用TokenAuthentication向另一个应用程序发送请求,该应用程序是使用Django Admin构建的CRM,因此使用SessionAuthentication。当我们打开Django Admin应用程序时,SessionMiddleware会自动为该域创建一个session_id cookie。在打开客户端应用程序并尝试执行请求时,我们收到以下错误:

Error: CSRF Failed: Referer checking failed - https://domainofthedjangoadminapp.com does not match any trusted origins.

这只是因为浏览器中已经设置了session_id cookie,因此请求使用了SessionAuthentication而不是TokenAuthentication,并失败了。

移除该cookie显然解决了问题。


5

2022年4月更新:

如果您的Django版本"4.x.x":

python -m django --version

// 4.x.x

如果出现以下错误:

来源检查失败 - https://example.com 与任何受信任的来源不匹配。

请在"settings.py"文件中添加以下代码:

CSRF_TRUSTED_ORIGINS = ['https://example.com']

在你的情况下,你遇到了类似于上面的错误:

错误:CSRF 失败:Referer 检查失败 - https://front.bluemix.net 不匹配任何受信任的来源。

所以,你需要将以下代码添加到你的 "settings.py"中:
CSRF_TRUSTED_ORIGINS = ['https://front.bluemix.net']

5
根据此文档:https://docs.djangoproject.com/en/4.0/releases/4.0/#csrf-trusted-origins-changes,CSRF信任的源头已经发生变化。
  1. install cors-header by: doing pip install django-cors-headers

  2. Add corsheaders to you installed apps

    INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'MyApp',
    'crispy_forms',
    'corsheaders',
    ]
    
  3. Add the corsheader Middleware to your middleware

    MIDDLEWARE = [
    '**corsheaders.middleware.CorsMiddleware**',
    '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',
     ]
    

4 设置原点

 CSRF_TRUSTED_ORIGINS = ['https://front.bluemix.net']

2
如果您将Cloudflare的SSL/TLS加密模式设置为Flexible,也可能会出现此问题。与其说网站实际上是通过Https提供服务,不如说Cloudflare在其端修改了http网站并设置了SSL。这导致了CSRF机制的失败,无论我如何设置CSRF,都会看到这个错误。关闭这个选项立即解决了这个错误。

1
如果您在Cloudflare中使用了灵活的TLS/SSL设置,将以下内容放入您的Django settings.py文件中:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接