禁止 (403) CSRF 验证失败。请求被中止。失败原因:来源检查失败与任何可信来源不匹配

问题描述 投票:0回答:5

帮助

失败原因:

Origin checking failed - https://praktikum6.jhoncena.repl.co does not match any trusted origins.

一般来说,当存在真正的跨站请求伪造,或者没有正确使用 Django 的 CSRF 机制时,就会发生这种情况。对于 POST 表单,您需要确保:

Your browser is accepting cookies.
The view function passes a request to the template’s render method.
In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
The form has a valid CSRF token. After logging in in another browser tab or hitting the back button after a login, you may need to reload the page with the form, because the token is rotated after a login.

您看到此页面的帮助部分是因为您的 Django 设置文件中有 DEBUG = True。将其更改为 False,则仅显示初始错误消息。

您可以使用 CSRF_FAILURE_VIEW 设置自定义此页面。

python python-3.x django csrf django-csrf
5个回答
159
投票

检查您是否使用 Django 4.0。我使用的是 3.2,升级到 4.0 时遇到了这个中断。

如果您使用的是 4.0,这是我的修复方法。将此行添加到您的

settings.py
。当我使用 3.2 时,这不是必需的,现在如果没有它,我无法发布包含 CSRF 的表单。

CSRF_TRUSTED_ORIGINS = ['https://*.mydomain.com','https://*.127.0.0.1']

查看此行是否需要进行任何更改,例如,是否需要将

https
替换为
http

根本原因是在 4.0 中添加了原始标头检查。

https://docs.djangoproject.com/en/4.0/ref/settings/#csrf-trusted-origins

Django 4.0 中的更改:

旧版本中不执行原始标头检查。


47
投票

2022 年 3 月更新:

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

python -m django --version

// 4.x.x

然后,如果报错如下图:

来源检查失败 - https://example.com 没有 匹配任何可信来源。

将此代码添加到“settings.py”

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

在您的情况下,您收到此错误:

来源检查失败 - https://praktikum6.jhoncena.repl.co 没有 匹配任何可信来源。

因此,您需要将此代码添加到您的“settings.py”

CSRF_TRUSTED_ORIGINS = ['https://praktikum6.jhoncena.repl.co']

36
投票

来源和主机是同一个域

如果像我一样,当源和主机 是同一域时,您会收到此错误。

可能是因为:

  1. 您正在通过 HTTPS 为您的 django 应用程序提供服务,
  2. 您的 django 应用程序位于代理后面,例如Nginx,
  3. 您忘记在 settings.py 中设置
    SECURE_PROXY_SSL_HEADER
    ,例如
    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
    和/或
  4. 您忘记在服务器配置中设置标头,例如
    proxy_set_header X-Forwarded-Proto https;
    用于 Nginx。

在这种情况下:

  • 由于 1,来自客户端浏览器的原始标头将是
    https://www.example.com
  • 由于 2、3 和 4,
  • request.is_secure()
    正在返回
    False
  • 含义
    _origin_verified()
    返回
    False
    ,因为django.middleware.csrf第285行(https://www.example.com
    http://www.example.com
    的比较):
def _origin_verified(self, request): request_origin = request.META["HTTP_ORIGIN"] try: good_host = request.get_host() except DisallowedHost: pass else: good_origin = "%s://%s" % ( "https" if request.is_secure() else "http", good_host, ) if request_origin == good_origin: return True

在更改此设置之前,请确保阅读https://docs.djangoproject.com/en/4.0/ref/settings/#secure-proxy-ssl-header中的警告!


0
投票
您也可能会遇到此错误,因为您在 Proxmox 上使用容器。

如果您的 https 域名是 Proxmox 通过内部 http 连接路由的,您将会遇到此错误。

域名 (https) => Proxmox => (http) => 带有 Django 的容器:CSRF 错误

我遇到了这个错误,并通过 https 内部连接将 Proxmox 的路由更改为我的容器(我必须在我的 CT 上创建并签署证书)。

域名 (hhtps) => Proxmox => (https) => Django 容器

自从 Django 上的 CSRF 错误消失后。


0
投票
如果有人将

.env

django-environenv.list()

必须在

.env 中设置像这样的

CSRF
原点

CSRF_TRUSTED_ORIGINS=one.example.com two.example.com
并像这样在

settings.py中访问它

CSRF_TRUSTED_ORIGINS = env.list('CSRF_TRUSTED_ORIGINS')
    
© www.soinside.com 2019 - 2024. All rights reserved.