首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >不用 Cookie,鉴权照样稳

不用 Cookie,鉴权照样稳

作者头像
程序员NEO
发布2026-04-29 19:37:12
发布2026-04-29 19:37:12
1330
举报
你有没有遇到过这种情况: 登录接口明明返回成功,前端紧接着请求用户信息却直接 401。 本地 Postman 一切正常,一上 H5/小程序就“玄学掉线”。

我最近把一套 Sa-Token 鉴权从传统 Web 改成前后端分离时,就踩了这坑。 这篇不讲空话,只讲可落地方案:不靠 Cookie,照样把登录态跑稳

一、问题背景:前后端分离后,Cookie 不再兜底

传统 Web 鉴权有两个“天然能力”:

  • • 后端可以写 Cookie
  • • 浏览器每次请求会自动带上 Cookie

但在 App、小程序、前后端分离场景里,这两个能力经常不存在。 所以你必须自己完成两件事:

  • • 登录后把 Token 存下来
  • • 每次请求手动把 Token 带回去

核心结论:无 Cookie 模式不是“不能鉴权”,而是“从自动提交改成手动提交”。

二、技术原理:Sa-Token 在无 Cookie 模式怎么读 Token

Sa-Token 默认能从多个位置读 Token(Header、Cookie、Body)。 前后端分离建议走 Header,链路最清晰。

后端登录成功后,拿到 tokenName + tokenValue 返回前端。 前端存储这两个值,请求时放入 Header:{tokenName: tokenValue}。 后端就能正常识别登录态。

三、工程实践(可直接改项目)

1)后端登录接口:返回 tokenName 和 tokenValue

代码语言:javascript
复制
@PostMapping("/user/doLogin")
public SaResult doLogin(@RequestBody LoginDTO dto) {
    Long userId = userService.checkLogin(dto.getUsername(), dto.getPassword());
    StpUtil.login(userId);

    SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
    // tokenInfo 里含 tokenName / tokenValue
    return SaResult.data(tokenInfo);
}

2)前端登录后存储 token

代码语言:javascript
复制
const res = await axios.post('/user/doLogin', form);
const { tokenName, tokenValue } = res.data.data;

localStorage.setItem('tokenName', tokenName);
localStorage.setItem('tokenValue', tokenValue);

3)统一请求拦截器:每次自动带 Token

代码语言:javascript
复制
axios.interceptors.request.use((config) => {
  const tokenName = localStorage.getItem('tokenName') || 'satoken';
  const tokenValue = localStorage.getItem('tokenValue');

  if (tokenValue) {
    config.headers[tokenName] = tokenValue;
  }
  return config;
});

4)后端配置:明确走 Header,关闭 Cookie 依赖

代码语言:javascript
复制
sa-token:
  token-name: satoken
  is-read-header: true
  is-read-cookie: false
  timeout: 2592000

5)用命令先自测链路(别直接上联调)

代码语言:javascript
复制
# 1. 登录拿 token
curl -X POST http://localhost:8080/user/doLogin \
  -H "Content-Type: application/json" \
  -d "{\"username\":\"neo\",\"password\":\"123456\"}"

# 2. 带 token 调受保护接口
curl http://localhost:8080/user/info \
  -H "satoken: 这里替换成上一步返回的tokenValue"

四、我踩过的 3 个高频坑(现象 + 原因 + 修复)

⚠️ 坑1:登录成功,但后续接口全 401

  • • 现象:/doLogin 成功,/user/info 401
  • • 原因:只存了 tokenValue,没存 tokenName,环境改过 token-name 后直接失配
  • • 修复:前端必须同时存 tokenName + tokenValue,动态组装 Header

⚠️ 坑2:Postman 正常,浏览器报跨域问题

  • • 现象:浏览器控制台提示 CORS 错误
  • • 原因:网关或后端没放行自定义请求头
  • • 修复:在跨域配置里放行业务头;联调时先确认预检请求是否通过

⚠️ 坑3:本地好好的,上网关后丢登录态

  • • 现象:直连服务正常,走网关后未登录
  • • 原因:网关安全策略只放行白名单头,satoken 被过滤
  • • 修复:把 Token 请求头加入网关放行列表,并做一条端到端回归用例

五、最终落地方案(我现在的固定做法)

🚀 我在项目里固定这套约定:

  1. 1. 登录接口统一返回 tokenName/tokenValue
  2. 2. 前端统一拦截器注入 Header,不在业务代码里手写
  3. 3. 后端无 Cookie 场景统一 is-read-cookie=false
  4. 4. 网关头部放行和跨域规则纳入发布检查清单

这套跑通后,H5、管理后台、小程序都能复用一套鉴权模型。

六、工程总结(3条可迁移认知)

  • 认知1:分离架构下,鉴权失败大多是“传递链路问题”,不是框架问题。
  • 认知2:把 Token 注入做成基础设施(拦截器),比靠人手写更稳。
  • 认知3:登录态问题一定要做“端到端自测”,只测单点接口意义不大。

参考文档:

  • • https://sa-token.cc/doc.html#/up/not-cookie
  • • https://github.com/dromara/sa-token/blob/master/sa-token-doc/up/not-cookie.md

相关文章推荐

如果这篇文章帮到了你,不妨点个分享给同样需要的朋友吧! 你的每一次支持,都是我持续创作的动力!💪

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-03-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员NEO 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、问题背景:前后端分离后,Cookie 不再兜底
  • 二、技术原理:Sa-Token 在无 Cookie 模式怎么读 Token
  • 三、工程实践(可直接改项目)
    • 1)后端登录接口:返回 tokenName 和 tokenValue
    • 2)前端登录后存储 token
    • 3)统一请求拦截器:每次自动带 Token
    • 4)后端配置:明确走 Header,关闭 Cookie 依赖
    • 5)用命令先自测链路(别直接上联调)
  • 四、我踩过的 3 个高频坑(现象 + 原因 + 修复)
    • ⚠️ 坑1:登录成功,但后续接口全 401
    • ⚠️ 坑2:Postman 正常,浏览器报跨域问题
    • ⚠️ 坑3:本地好好的,上网关后丢登录态
  • 五、最终落地方案(我现在的固定做法)
  • 六、工程总结(3条可迁移认知)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档