vue调用django api出现401或csrf token missing,根本原因是django默认启用csrf保护而axios不自动携带x-csrftoken头;需前端登录后获取token并手动注入请求头,django端配置csrf_cookie_httponly=false、samesite适配跨域,并确保cors与cookie域、https代理头等生产环境设置正确。

Vue调用Django API时401或CSRF token missing怎么办
不是Django不认Vue发的请求,是默认启用了CSRF保护,而Vue(尤其用axios)默认不带X-CSRFToken头,也不读取csrftoken cookie。Django收到非GET/HEAD请求(比如POST登录、提交表单),直接拒绝。
实操建议:
- 前端在登录成功后,从响应头或单独接口(如
/api/csrf-token/)拿到csrftoken值,存入内存(别存localStorage) - 后续所有带body的请求(POST/PUT/PATCH/DELETE),必须手动加
headers: {'X-CSRFToken': token} - Django端确保
settings.py里CSRF_COOKIE_HTTPONLY=False(否则JS读不到cookie),且CSRF_COOKIE_SAMESITE='Lax'或'None'(若跨域需'None'并配CSRF_COOKIE_SECURE=True) - 如果完全不想碰CSRF(比如纯API场景),可对特定视图禁用:用
@csrf_exempt装饰器,但仅限于已用JWT或Session认证的接口——别裸奔
Django REST Framework怎么返回Vue能直接用的用户登录态
Vue需要知道“当前谁登录了”“有没有权限”,但Django Session依赖cookie,跨域时浏览器默认不发凭据;JWT又得自己签发校验。最稳的路是让Django在登录成功后,把用户关键字段(id、username、is_staff等)塞进响应体,而不是只扔个sessionid。
实操建议:
- 用
django.contrib.auth.login()完成认证后,立刻查request.user,序列化成字典返回,例如:{'user': {'id': user.id, 'username': user.username, 'is_authenticated': True}} - 别依赖
request.session.session_key返回给前端——它没意义,Session ID本就由浏览器自动管理 - 如果用JWT,推荐
djangorestframework-simplejwt,但注意:它的AccessToken默认不包含用户字段,需自定义TokenObtainPairSerializer往payload里加user_id、username - Vue收到响应后,把
user对象存Vuex/Pinia,路由守卫靠它判断登录态,别反复调/api/user/
Vue开发服务器(localhost:8080)访问Django(localhost:8000)被CORS拦截
浏览器报错Access to fetch at 'http://localhost:8000/api/login/' from origin 'http://localhost:8080' has been blocked by CORS policy,本质是Django没声明允许这个源发起请求,连预检(OPTIONS)都过不去。
实操建议:
- 装
django-cors-headers,在INSTALLED_APPS加'corsheaders',中间件里插在CommonMiddleware之前 - 开发期直接放开:
CORS_ALLOWED_ORIGINS = ['http://localhost:8080'](别写*,它不支持带credentials的请求) - 必须配
CORS_ALLOW_CREDENTIALS = True,否则axios设withCredentials: true会失败 - 如果Vue用
file://协议打开(比如双击index.html),CORS无解——必须走本地服务器(serve或http-server)
生产环境Nginx反向代理后,Django的SESSION_COOKIE_DOMAIN和SECURE设置怎么配
Vue打包后放Nginx,Django也跑在Nginx下,但域名统一为app.example.com。此时若Django还按localhost设cookie域,或漏掉HTTPS相关开关,Session就断连、登录态秒丢。
实操建议:
-
SESSION_COOKIE_DOMAIN = '.example.com'(开头带点,兼容子域名);CSRF_COOKIE_DOMAIN同理 - 如果Nginx终止HTTPS,Django收的是HTTP请求,但实际是HTTPS进来——必须加
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') -
SECURE_COOKIE = True和SESSION_COOKIE_SECURE = True必须开,否则浏览器不传cookie -
SECURE_REFERRER_POLICY = 'same-origin',避免Referrer泄露敏感路径
跨域联调真正的麻烦不在代码,在cookie作用域和协议信任链上。一个配置项写错,整个身份验证就静默失效,Vue看起来一切正常,但Django日志里全是Forbidden (CSRF token missing)或Forbidden (Referer checking failed)——得盯住浏览器开发者工具的Application → Cookies和Network → Request Headers两栏才看得见问题。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











