如何实现Django重定向至Vue应用时无需用户二次登录
Django跳转Vue管理端免二次登录最优实现方案
最推荐用短时效JWT单次签名跳转方案,没有跨域兼容问题,改造成本极低,安全性足够,完全适配Django模板渲染+Vue前后端分离的架构,不用额外搭建重型SSO服务。
核心逻辑
放弃跨域共享Cookie的思路(当前浏览器默认SameSite策略对跨域Cookie限制极严,适配坑多),流程全程用户无感知:
- 用户在Django站点处于已登录状态,点击跳转按钮时,Django后端校验用户身份后,生成一个仅用于单次跳转、有效期极短的签名令牌
- 携带该令牌重定向到Vue管理端地址
- Vue端拿到令牌后立刻调用Django接口校验身份,换取Vue端自身的正式登录凭证,完成自动登录,全程不展示登录页
具体实现步骤
Django端开发
- 安装依赖:执行
pip install pyjwt引入轻量JWT库,不需要额外引入重型认证框架。 - 配置密钥:在Django的
settings.py里加一个专门用于SSO跳转的签名密钥,别硬编码在代码里,从环境变量读取就行。 - 编写跳转入口视图:
- 首先校验当前请求用户是否为登录状态,未登录直接跳转Django自带的登录页
- 生成JWT令牌,payload仅保留必要字段:当前用户ID、令牌过期时间(设置为10秒即可,足够完成一次跳转)、用途标记(固定值比如
sso_jump_to_admin,防止令牌被挪作他用)、唯一令牌ID(jti,用于做一次性校验) - 生成令牌后,直接重定向到Vue管理端的入口地址,把令牌拼在URL query参数里,比如
https://你的vue管理端域名/?sso_token=xxx
- 编写令牌校验接口(给Vue端调用):
- 接收Vue端传来的
sso_token,用同一个密钥验签,依次判断签名是否合法、是否过期、用途标记是否匹配、jti是否已经被使用过(存在Redis里判重,用过的jti存1分钟自动过期) - 所有校验通过后,按照Vue端原有登录的返回格式,返回对应的access_token、refresh_token、用户基础信息,和正常账号密码登录成功的返回结构完全一致
- 任意校验不通过直接返回401状态码
- 接收Vue端传来的
- 在原有Django模板里添加跳转按钮,链接指向刚才写的跳转入口视图的路由即可。
Vue端开发
- 在路由全局前置守卫里加判断逻辑:
- 如果当前URL的query参数里携带
sso_token,第一时间把该参数从URL中清除,避免令牌残留在地址栏、浏览记录里造成泄露 - 取出
sso_token调用Django端的校验接口,拿到正式登录凭证后,按照原有登录逻辑把凭证存在本地存储/Vuex/pinia里 - 凭证存储完成后直接跳转至管理端首页,用户无感知
- 如果当前URL的query参数里携带
- 如果URL里没有
sso_token,走原有登录态校验逻辑即可:本地存在有效凭证就正常访问页面,不存在就跳转Vue端自己的登录页。
方案优势&避坑说明
- 无跨域限制:哪怕Django站点和Vue管理端部署在完全不同的一级域名下也能正常使用,不需要调整Cookie跨域配置,不需要做域名同根规划
- 安全性高:临时令牌有效期极短,且仅能使用一次,就算令牌被截获也几乎没有被利用的可能;注意JWT payload是Base64编码可解码的,不要在里面存密码等敏感信息
- 改造成本极低:不需要推翻Django端原有模板认证逻辑,也不需要修改Vue端已有的登录流程,仅需新增2个简单接口、一段路由判断,单天即可完成开发调试
- 避坑提醒:不要直接把Django的sessionid拼在URL里跳转,sessionid有效期过长,泄露风险极高;不要为了省事儿硬搞跨域Cookie共享,不同浏览器、不同版本的SameSite默认策略差异大,后续维护踩坑成本极高;两个内部系统跳转没必要上OAuth2、CAS这类重型SSO框架,徒增维护成本。
内容的提问来源于stack exchange,提问作者user15117822
相关产品推荐
相关产品推荐

