You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django生产环境仅登录时出现403 Forbidden(CSRF验证失败)问题

Django生产环境登录表单CSRF验证失败问题

问题现象

使用Django自带的Login/authentication登录认证功能,在生产环境提交登录POST请求时触发403 Forbidden错误,提示:

CSRF verification failed. Request aborted.
具体原因:CSRF cookie not set.

该问题仅出现在登录表单,应用内其他表单无异常;本地环境登录功能正常;生产环境中先访问admin再登录可正常使用,但关闭浏览器后重新登录又触发403错误。使用Django 3.2版本。

登录表单代码

{% extends "main/base.html" %}
{% load static %}
{% load widget_tweaks %}

{% block content%}

<div class='container'>
    <div class='row pt-4'>
        <div class="col">
        </div>
        <div class="col-md-4 col-md-offset-4">
            <div class="card text-center">
                <!-- Login Form -->
                <div class="card-header bg-dark">
                    <h2 class="text-secondary">Login</h2>
                </div>
                <div class="card-body card text-left">
                    <form method="POST">
                        {% csrf_token %}
                        {% for hidden in form.hidden_fields %}
                        {{ hidden }}
                        {% endfor %}
                        {% for field in form.visible_fields %}
                        <div class="form-group">
                            <label>{{ field.label_tag }}</label>
                            {% render_field field class="form-control" %}
                            {% for error in field.errors %}
                            <span class="help-block">{{ error }}</span>
                            {% endfor %}
                        </div>
                        {% endfor %}
                        <div class="form-group">
                        <p>¿Olvidaste tú usuario o contraseña?<a href=""> Click aquí!</a></p>
                        </div>
                        <div class="form-group">
                            <button type="submit" class="btn btn-primary">Ingresar</button>
                        </div>
                    </form>
                </div>
            </div>
        </div>
        <div class="col">
        </div>
    </div>
</div>

{% endblock %}

已尝试的Settings配置

ALLOWED_HOSTS = ['http://*', 'https://*'] # 也试过填写具体URL
CSRF_TRUSTED_ORIGINS = ['http://*', 'https://*'] # 也试过填写具体URL
CSRF_COOKIE_SECURE = True # 也试过设为False
SESSION_COOKIE_SECURE = True # 也试过设为False

网络请求截图

登录请求网络截图


解决方案

1. 配置CSRF Cookie的Domain属性

生产环境中,浏览器可能因为Cookie的Domain不匹配而拒绝保存CSRF Cookie。在settings.py中添加:

# 替换为你的生产域名,比如 example.com,不要加http/https前缀
CSRF_COOKIE_DOMAIN = "your-production-domain.com"
# 如果是子域名场景,设置为 .your-production-domain.com(注意开头的点)

2. 确认登录视图使用官方认证视图

确保登录路由指向Django自带的LoginView,避免自定义视图未正确处理CSRF逻辑。urls.py示例:

from django.contrib.auth.views import LoginView

urlpatterns = [
    # ...
    path('login/', LoginView.as_view(template_name='你的登录模板路径'), name='login'),
]

3. 修复反向代理(如Nginx)的请求头传递

如果生产环境使用反向代理,需确保请求头正确传递给Django,否则Django无法识别正确的请求来源。以Nginx为例,在配置中添加:

proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Real-IP $remote_addr;

同时在settings.py中启用相关配置:

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
USE_X_FORWARDED_HOST = True

4. 调整CSRF Cookie的SameSite属性

现代浏览器对Cookie的SameSite属性限制严格,在settings.py中设置合适的值:

# 常规场景用Lax即可
CSRF_COOKIE_SAMESITE = 'Lax'
# 如果是跨域登录场景,设置为None,但必须配合CSRF_COOKIE_SECURE=True
# CSRF_COOKIE_SAMESITE = 'None'
# CSRF_COOKIE_SECURE = True

5. 清除浏览器缓存测试

旧的Cookie或缓存可能导致冲突,测试时使用浏览器隐私模式,或手动清除对应域名的Cookie和缓存后重试。


内容的提问来源于stack exchange,提问作者Jorge López

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 12:10:55