drf的tokenauthentication不能直接用于vue单页应用,因其依赖手动注入authorization头、不支持token过期与刷新,且缺乏配套登录视图;应改用djangorestframework-simplejwt,配合axios拦截器、sessionstorage存储及后端jwt配置。

DRF的TokenAuthentication为什么不能直接用于Vue单页应用
因为 TokenAuthentication 默认依赖 HTTP 请求头中的 Authorization: Token xxx,而 Vue 前端发起请求时不会自动携带该头——它不像 Django 模板渲染那样能隐式注入 CSRF 和 session 信息。更关键的是,原生 TokenAuthentication 不支持 Token 过期、刷新、用户绑定设备等常见需求,一用就卡在登录后 401 或跨域请求被拒。
实操建议:
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
- 别直接用
rest_framework.authentication.TokenAuthentication,它只是个基础验证器,没配套的登录/登出视图和 Token 生命周期管理 - 改用
djangorestframework-simplejwt(推荐)或drf-token-refresh,它们提供标准的/api/token/、/api/token/refresh/接口,Vue 可以用 Axios 统一拦截器注入Authorization头 - 确保 Django 的
CORS_ORIGIN_WHITELIST(或CORS_ALLOWED_ORIGINS)包含 Vue 开发服务器地址,比如"http://localhost:5173",否则预检请求(OPTIONS)直接失败 - 前端必须手动保存 Token 到
localStorage或sessionStorage,且每次请求前读取并设置headers.Authorization = `Bearer ${token}`
Vue 中如何安全地存储和传递 JWT Token
localStorage 看似方便,但 XSS 攻击可直接读取;放在 Cookie 里又得处理 HttpOnly 和 SameSite 限制。折中方案是:用 sessionStorage 存 Token + Axios 请求拦截器统一注入,同时后端设置 Token 短期有效(如 15 分钟),强制前端调用 /api/token/refresh/ 获取新 Token。
实操建议:
- 登录成功后,把响应里的
access和refresh字段分别存入sessionStorage:sessionStorage.setItem('access_token', response.data.access) - Axios 全局请求拦截器中读取:
config.headers.Authorization = 'Bearer ' + sessionStorage.getItem('access_token'),注意判空避免 401 泛滥 - 对 401 响应做单独拦截:若错误是
"Token is invalid or expired",则用refreshToken 尝试续期;失败再跳转登录页 - 不要在 Vue Router 的
beforeEach里反复读取 Token 并校验——那是后端的事,前端只负责透传
Django 后端如何配置 simplejwt 并兼容 Vue 跨域请求
simplejwt 默认返回的 Token 不带过期时间字段,Vue 很难做自动刷新判断;另外它的默认签名密钥是硬编码的 SIMPLE_JWT['SIGNING_KEY'],生产环境必须替换为环境变量读取的密钥,否则部署多实例时 Token 校验会失败。
实操建议:
- 安装后,在
settings.py中配置:SIMPLE_JWT字典必须显式定义'ACCESS_TOKEN_LIFETIME'和'REFRESH_TOKEN_LIFETIME',单位是timedelta,例如timedelta(minutes=15) - 加上
'AUTH_HEADER_TYPES': ('Bearer',),否则 Vue 发送Authorization: Bearer xxx会被忽略 - 在
urls.py中注册路由:path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),并确保该视图返回的 JSON 包含access、refresh、user_id(需自定义序列化器) - 如果 Vue 部署在独立域名(如
app.example.com),Django 必须开启CORS_ALLOW_CREDENTIALS = True,且前端 Axios 配置withCredentials: true,否则 Cookie 中的 session 无法共享(虽然 Token 认证不用 Session,但某些调试场景会混用)
为什么登录后 Vue 能拿到 Token 却始终 403 —— 权限类没配对
TokenAuthentication 或 JWTAuthentication 只负责「识别用户是谁」,不等于「允许访问」。如果你在 ViewSet 中写了 permission_classes = [IsAuthenticated] 却没启用认证类,或者用了 SessionAuthentication 但前端没传 sessionid Cookie,就会返回 403 而非 401,让人误以为是权限问题。
实操建议:
- 检查视图的
authentication_classes是否显式声明了[JWTAuthentication](来自simplejwt)或[TokenAuthentication](来自 DRF),不能只靠全局配置,局部覆盖容易遗漏 - 确认
DEFAULT_AUTHENTICATION_CLASSES在settings.py中已替换掉默认的SessionAuthentication,例如:'rest_framework_simplejwt.authentication.JWTAuthentication' - 用 curl 手动测试接口是否生效:
curl -H "Authorization: Bearer <your-token>" http://localhost:8000/api/test/</your-token>,排除前端 JS 逻辑干扰 - 如果用了自定义 Permission 类(比如基于用户角色),确保它继承自
BasePermission而非permissions.IsAuthenticated,后者在未认证时返回 401,而前者可能静默拒绝
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










