1 · 拆分 TokenService:三个概念从宽接口里各归其位
crm-auth/.../security/TokenService.java(212 行,12 个公开方法)
crm-auth/.../service/impl/AuthServiceImpl.java · security/JwtAuthenticationFilter.java · controller/DebugTokenController.java
Before — 一个宽接口扛三个概念
interface
12 方法
implementation
212 行
JWT 密码学 + 单端在线会话索引 + 预登录票 + 被顶下线标记同居一类;
接口几乎与实现等宽 —— shallow
After — 三个深模块
JwtCodec
SessionStore
TicketStore
橙色 = interface,深色 = implementation;接口收窄,实现变深
Problem
「每个 (userId, 端类型) 至多一个活会话」这条核心安全不变量没有一个专属的 module 负责——它分散在 12 个平铺方法之间,靠调用方的调用顺序维系。
Solution
按概念拆成三个深模块:无状态 JwtCodec、独占单端在线不变量的 SessionStore、独立的预登录票 store;编排上移到本就该知道顺序的调用方。
- • locality:单端在线不变量有一个明确的家和专属测试
- • JwtCodec 无状态不碰 Redis,纯密码学单测即可覆盖
- • 每请求热路径(JwtAuthenticationFilter)只依赖它真正需要的那一小片 interface
- • 登录编排测试不再 mock 一个 12 方法的门面