Spring Boot 多模块服务间 API Token 鉴权排查记录

这次需求是:配送端调用用户端的消息、下单、开柜接口时,不再使用普通用户登录 JWT,而是使用服务间 API Token 鉴权。

整体调用链:

问题一:多个工具类各自维护 Token

NoticeUtils 用 Redis 缓存 token,StorageApiUtils 用本地内存缓存 token。两套逻辑会导致:

同一个服务可能重复申请 token。

token 的过期、刷新策略不一致。

多实例部署时,本地内存无法共享。

解决方法:抽取 StorageApiTokenProvider。

统一调用 /dali/internal/auth/token。

使用同一个 Redis key 缓存 token。

NoticeUtils、StorageApiUtils 都从 Provider 获取 token。

token 临近过期时提前刷新。

业务接口返回 401/403 时,删除缓存、重新申请 token,并只重试一次。

问题二:API Token 请求进不了 AuthInterceptor

用户端原来已有 AuthorizationFilter,用于校验普通用户 JWT。

Filter 的执行顺序早于 Spring MVC 的 AuthInterceptor。配送端请求只携带:

复制代码
X-Api-Client: lida-delivery-order
X-Api-Token: xxx

没有普通用户 JWT,因此旧 Filter 会先拦截请求,AuthInterceptor 根本没有机会校验 API Token。

一开始想到把接口加入 JWT Filter 白名单,但这会绕过鉴权,且不符合安全要求。

正确方案不是白名单,而是区分两种身份:

普通请求:继续使用 JWT 校验。

带 X-Api-Client 或 X-Api-Token 的服务间请求:不在旧 Filter 中按 JWT 拦截,继续交给 AuthInterceptor。

AuthInterceptor 只允许 API Token 访问标注了 @ApiTokenRequired 的接口。

带 API Token 访问普通接口时直接拒绝。

这样既保留了普通用户 JWT 鉴权,也让服务间 API Token 有独立且受限的鉴权入口。

问题三:Read timed out 不一定是网络问题

配送端调用通知接口时出现:

复制代码
cn.hutool.http.HttpException: Read timed out

排查后发现,用户端服务正在断点调试。服务端线程停在断点期间,配送端 HTTP 客户端只等待 5 秒:

复制代码
.timeout(5000)

超过 5 秒后,配送端主动超时;继续运行服务端后,用户端仍会继续执行请求。

结论:调试服务间 HTTP 调用时,断点停留时间不能超过客户端超时时间。否则会误以为是网络或鉴权问题。

问题四:空测试参数触发空指针

测试代码传入了空对象:

复制代码
noticeUtils.sendNotice(new WxMessageSendReq());

用户端 Controller 中直接调用:

复制代码
req.getWxMessageBusinessType().equals(...)

因为 wxMessageBusinessType 为 null,导致空指针。

修复为常量放左边:

复制代码
WxMessageBusinessCodeEnum.PICK_UP_SUCCESS.getType()
    .equals(req.getWxMessageBusinessType())

这样即使字段为空,也不会抛系统异常,而是继续返回明确的业务失败信息,例如:

复制代码
{
  "code": 200,
  "data": {
    "isSuccess": false,
    "msg": "用户userId为空"
  }
}
相关推荐
吴声子夜歌7 分钟前
Java面试——Spring Cloud原理及应用(二)
java·spring cloud·面试
SomeB1oody27 分钟前
【RustyML入门】6.3. 并行归约
开发语言·后端·机器学习·rust·教程
东小西1 小时前
【SAA实战】第 1 篇:ReactAgent 入门——先撸个"会调工具的助手"跑起来
java·人工智能·spring
Profile排查笔记1 小时前
指纹浏览器哪个好?从 Profile、代理、权限和自动化能力判断是否适合
前端·人工智能·后端·自动化
用户938515635072 小时前
用 AI 结对编程从 0 搭一个"单词后台管理系统":Next.js + Supabase + Drizzle + shadcn/ui 全记录
后端·postgresql·next.js
mqiqe2 小时前
AgentScope Java 2.0 协议集成全景解析:A2A、AG-UI、Agent Protocol 三大开放协议实战指南
java·开发语言·ui
脉动数据行情2 小时前
Java 实现台股 TWSE/TPEx 行情采集(个股 + K 线)
java·开发语言·twse·tpex·台股
爱学习的小邓同学2 小时前
Golang --- (1)第一个Golang程序
开发语言·后端·golang
小灰灰搞电子3 小时前
Rust+Slint 实现的“DNA双螺旋”加载动画源码分享
后端·rust·slint·加载动画
面向Google编程3 小时前
向量库不再囤数据:Milvus 3.0 零拷贝直读数据湖
后端