【问题标题】:Production only: sometimes get 403 CSRF verification failed仅限生产:有时会收到 403 CSRF 验证失败
【发布时间】:2015-10-15 10:51:49
【问题描述】:

我有一个登录表单,可以将用户登录到管理站点。它在开发中运行良好,并且在生产中大部分运行良好,但有时它会给出 403 CSRF 验证失败错误。请注意,这发生在之前能够登录的用户身上,所以我无法想象这是他们的浏览器的问题。

看起来 jenniwren 在this comment 中遇到了类似的问题。他们从来没有问过这个问题,其他评论者也不知道为什么会发生这种情况。

这是我所拥有的:

urls.py

urlpatterns += patterns('django.contrib.auth.views',
    url(r'^logout$', 'logout', {'next_page': 'mysite_login'}, name='mysite_logout'),
    url(r'^login$', 'login', name='mysite_login'),

    url('^', include('django.contrib.auth.urls')),
)

ma​​in/registration/login.html

{% extends "base.html" %}
{% load staticfiles %}

{% block content %}
    {% if form.errors and not form.non_field_errors %}
        <p class="errornote">Please correct the error(s) below.</p>
    {% endif %}

    {% if form.non_field_errors %}
        {% for error in form.non_field_errors %}
            <p class="errornote">
                {{ error }}
            </p>
        {% endfor %}
    {% endif %}

    <form action="{{ app_path }}" method="post" id="login-form">
        {% csrf_token %}

        <div class="form-row">
            {% if form.errors %}
                { form.username.errors }}
            {% endif %}
            {{ form.username.label_tag }}
            {{ form.username }}
        </div>
        <div class="form-row">
            {% if form.errors %}
                {{ form.password.errors }}
            {% endif %}
            {{ form.password.label_tag }}
            {{ form.password }}
        </div>
        <input type="hidden" name="next" value="{{ next }}" />

        <div class="submit-row">
            <input type="submit" value="Log in" />
        </div>

        <div class="password-reset-link">
            <a href="{% url 'password_reset' %}">Forgot your password?</a>
        </div>
    </form>
{% endblock content %}

settings.py

INSTALLED_APPS = (
    'filebrowser',
    'grappelli',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'psycopg2',
    'main',
    'mysite'
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware'
)

SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_BROWSER_XSS_FILTER = True
CSRF_COOKIE_HTTPONLY = True

【问题讨论】:

    标签: python django django-admin


    【解决方案1】:

    如果出现以下情况,可能会出现此问题:

    1. 用户在两个不同的选项卡中打开登录页面
    2. 用户在一个选项卡中登录。
    3. 用户尝试在不同的选项卡中再次登录(尽管他已经登录)。

    如果您的CSRF_FAILURE_VIEW 显示您的网站模板,您也许可以让用户知道他们已经登录,并且不需要刷新页面。

    【讨论】:

      【解决方案2】:

      这是我在 Debug=True 时收到的消息:

      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.

      【讨论】:

        【解决方案3】:

        我觉得这个answer对你有帮助,你也可以使用@csrf_exempt注解 像这样在你的函数(视图)上:

        @csrf_exempt
        def foo():
           return 'bar'
        

        关于这个主题的 django 文档:https://docs.djangoproject.com/en/3.0/ref/csrf/

        【讨论】:

          【解决方案4】:

          我正在为管理员 URL 做一些代理,并通过编辑我的 settings.py 文件并添加:

          CSRF_TRUSTED_ORIGINS = [".subdomain.com"]

          使用我组织的 gsuite 子域。请参阅django docs 以供参考

          【讨论】:

            猜你喜欢
            • 2017-03-29
            • 2011-11-18
            • 1970-01-01
            • 2020-05-04
            • 2014-11-15
            • 1970-01-01
            • 2017-05-11
            • 2016-01-04
            • 2018-06-06
            相关资源
            最近更新 更多