Django-Vue-Admin 登录态“时好时坏”的 500 字速修(跨域/同域都适用)
症状:前端偶发被登出;刷新后接口 401;本地好、预发/生产不稳。多半是 Cookie/SameSite/HTTPS/CSRF 组合没对齐。下面 5 步,把坑一次填平(无外链)。
1) 统一域与 HTTPS
前后端都走 同主域(如 app.example.com / api.example.com)。
反向代理正确透传协议:
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $host;
2) Django 会话与 CSRF 设置
settings.py
SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True SESSION_COOKIE_SAMESITE = "None" # 前后端分离跨域时用 None CSRF_COOKIE_SAMESITE = "None"
CSRF_TRUSTED_ORIGINS = [ "https://app.example.com", "https://admin.example.com", ]
若同域同源,可把两项 Samesite 设为 "Lax",更稳更省心。
3) 前端携带凭证 & 取 CSRF
// axios 基础配置
const http = axios.create({
baseURL: "/api",
withCredentials: true, // 关键:带上 Cookie
});
// 初始化:先获取 CSRF
await http.get("/csrf/"); // 后端返回 csrftoken Cookie
// 之后请求自动带 Cookie;POST/PUT 需额外头:
http.post("/login", data, {
headers: { "X-CSRFToken": getCookie("csrftoken") }
});
4) DRF/登录视图防跨站
urls.py 中提供一个 csrf 获取端点
from django.views.decorators.csrf import ensure_csrf_cookie
from django.http import JsonResponse
@ensure_csrf_cookie
def csrf_view(_):
return JsonResponse({"ok": True})
### DRF 认证:SessionAuth + CSRF 校验
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework.authentication.SessionAuthentication",
]
}
5) 自检清单(线下 10 分钟)
浏览器 Cookie 标志:Secure=True、SameSite=None/Lax、域正确
登录前已命中 /csrf/,存在 csrftoken
所有修改类请求带 X-CSRFToken
代理已传 X-Forwarded-Proto=https
统一从 查看源代码 而非审查元素确认 /Cookie 生效
记忆法:“同域 HTTPS → 先取 CSRF → withCredentials → SameSite 对齐”。先把稳定性拉满,再考虑优化体验(如长会话、刷新令牌等)。
评论 0