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

Eri*_*hri 80 python django csrf django-csrf python-3.x

帮助

\n

失败原因给出:

\n
Origin checking failed - https://praktikum6.jhoncena.repl.co does not match any trusted origins.\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
Your browser is accepting cookies.\nThe view function passes a request to the template\xe2\x80\x99s render method.\nIn the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.\nIf 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.\nThe 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.\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

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

\n

Rya*_*ath 185

如果您正在进行跨源请求,您可能会看到此错误。例如,如果您从 site.example.com 上的网页向 api.example.com 提交表单,则这是跨源请求,可能会导致此错误。(如果您没有进行跨域请求,而是通过 HTTPS 进行正常请求,请参阅其他答案。)

\n

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

\n

如果你使用的是 4.0,这是我的修复方法。将此行添加到您的settings.py. 当我使用 3.2 时,这不是必需的,现在我无法在没有它的情况下发布包含 CSRF 的表单。

\n

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

\n

检查此行是否需要进行任何更改,例如,如果您需要https换成http.

\n

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

\n

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

\n
\n

Django 4.0 中的更改:

\n

旧版本中不执行原始标头检查\xe2\x80\x99。

\n
\n

  • 如果我已经使用“ALLOWED_HOSTS”设置来获取从环境变量设置的值,是否有任何理由不将“CSRF_TRUSTED_ORIGINS”设置为相同的值?IE `os.getenv('ALLOWED_HOSTS').split(',')`? (3认同)
  • 仅当您实际执行跨源请求(即从 site.example.com 上的页面向 api.example.com 提交表单)时才应执行此操作。如果您不尝试执行此(罕见)操作,则可能是另一个答案中所述的“SECURE_PROXY_SSL_HEADER”设置。 (2认同)

小智 55

来源和主机是同一个域

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

可能是因为:

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

在这种情况下:

  • 来自客户端浏览器的原始标头将归因https://www.example.com于 1。
  • request.is_secure()False由于 2、3 和 4正在返回。
  • 由于django.middleware.csrf 的第 285 行,含义_origin_verified()返回(与 的比较):Falsehttps://www.example.comhttp://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
Run Code Online (Sandbox Code Playgroud)

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

  • 实际上,这个答案是修复此错误的正确方法。它修复了两个问题,一个是 CSRF 检查,另一个是“request.is_secure()”值,在这种情况下它应该返回“True”。通过更新“CSRF_TRUSTED_ORIGINS”,您可以修复它,但我认为它是黑客,它只解决了这个问题。 (4认同)

小智 53

2022 年 3 月更新:

如果您的django 版本“4.xx”

python -m django --version

// 4.x.x
Run Code Online (Sandbox Code Playgroud)

那么如果报错如下图:

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

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

CSRF_TRUSTED_ORIGINS = ['https://example.com']
Run Code Online (Sandbox Code Playgroud)

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

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

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

CSRF_TRUSTED_ORIGINS = ['https://praktikum6.jhoncena.repl.co']
Run Code Online (Sandbox Code Playgroud)

  • 仅当您实际执行跨源请求(即从 site.example.com 上的页面向 api.example.com 提交表单)时才应执行此操作。如果您不尝试执行此(罕见)操作,则可能是另一个答案中所述的“SECURE_PROXY_SSL_HEADER”设置。 (4认同)