Django - 403 禁止 CSRF 验证失败

Posted

技术标签:

【中文标题】Django - 403 禁止 CSRF 验证失败【英文标题】:Django - 403 Forbidden CSRF verification failed 【发布时间】:2014-11-15 06:22:32 【问题描述】:

我的网站在 Django 中有一个联系表单,当我在本地对其进行测试时,它工作正常,但现在当我尝试“实时”提交我的联系表单时,它总是出现 403 Forbidden CSRF verification failed。

查看:

def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            send_mail(
                cd['subject'],
                cd['message'],
                cd.get('email', 'noreply@example.org'),
                ['example@gmail.com'],
            )
            return HttpResponseRedirect('/thanks/')
    else:
        form = ContactForm()
    return render(request, 'contact/contact.html', 'form': form)

contact.html

% extends 'site_base.html' %

% block head_title %Contact% endblock %

% block body %

      <h2>Contact Us</h2>
      <p>To send us a message, fill out the below form.</p>

    % if form.errors %
        <p style="color: red;">
            Please correct the error form.errors|pluralize  below.
        </p>
    % endif %

    <form action="" method="POST">
    % csrf_token %
        <table>
             form.as_table 
        </table>
        <br />
        <button type="submit" value="Submit" class="btn btn-primary">Submit</button>
    </form>    

% endblock %

设置(我认为相关的设置):

SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
MIDDLEWARE_CLASSES = [
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

在尝试排除一些事情之后,这就是我发现的。当我注释掉 SESSION_COOKIE_SECURE = TRUECSRF_COOKIE_SECURE = TRUESESSION_EXPIRE_AT_BROWSER_CLOSE = TRUE 时,它没有问题。

如果我只是注释掉 CSRF_COOKIE_SECURE = TRUE 它工作正常。我处理 CSRF 的方式似乎发生了一些奇怪的事情......任何帮助都会很棒。

【问题讨论】:

您是否通过https 为您的网站提供服务? 整个网站是这样的,还是只是表单提交?如果浏览器最初通过http 发送cookie,我认为它不会在通过https 提交表单时返回它。 【参考方案1】:

在我看来,当您注释掉该行时,如果它可以工作,那么该网站不是 https? CSRF_COOKIE_SECURE=True 根据文档 https://docs.djangoproject.com/en/1.7/ref/settings/#csrf-cookie-secure

使 csrf 令牌与 ssl 一起使用

【讨论】:

是的,这似乎是问题所在。我现在不需要我的网站使用 https,所以我暂时将其注释掉。谢谢! @webbyfox:真的吗?只是禁用 csrf 保护?

以上是关于Django - 403 禁止 CSRF 验证失败的主要内容,如果未能解决你的问题,请参考以下文章

禁止 (403) CSRF 验证失败。请求中止。即使使用 % csrf_token %

Django - 403 禁止。 CSRF 令牌丢失或不正确

禁止 403:Firefox 中的 CSRF 验证失败错误,而不是 chrome

为啥 Django 管理员登录给我 403 CSRF 错误?

Django POST 请求失败

django nginx 在生产中通过 http 获取 csrf 验证错误