Conversation
14 tasks
luoqiz
force-pushed
the
feat-refresh-token
branch
2 times, most recently
from
September 9, 2026 05:41
949bbb4 to
3763ec7
Compare
Charles7c
reviewed
Sep 9, 2026
luoqiz
force-pushed
the
feat-refresh-token
branch
from
September 9, 2026 23:10
8e3adc1 to
a40fe6a
Compare
Member
|
/continew-code-review |
为管理端 Web、App 与小程序提供可轮换的 Refresh Token 登录态:缩短 Access Token 生命周期,过期后由 Refresh Token 安全恢复原登录会话, 并支持跨端会话统一失效(强退、顶下线、密码修改、租户/客户端禁用)。 - 新增独立 continew-auth-refresh 模块:Refresh Token 签发、轮换、 重放保护、会话查询与失效;令牌采用 sessionId.secret 无状态格式, 服务端仅保存 HMAC-SHA256 指纹并做常量时间比对 - 轮换 R0→R1 由 LATEST 指纹门禁原子完成,宽限期内并发/重复请求 幂等返回首次结果;AES-GCM 快照保证崩溃后恢复一致 - 统一撤销收敛于会话锁内完成(策略锁→会话锁固定顺序),撤销后经 Redisson RTopic 广播 WebSocket 通知与访问会话缓存失效,其它实例 子秒级关闭对应实时连接 - 已登录请求的会话校验命中 Caffeine 本地缓存(TTL 2s)时为 0 次 Redis 往返,未命中一律回源全量校验,正确性不依赖缓存 - 多连接 WebSocket 会话 DAO:同一 Access Token 的多标签页连接互不 覆盖,撤销时全量关闭;本实例维持令牌→会话本地索引,批量撤销免于 逐连接回源 - Web 端经 HttpOnly Cookie 传输、App/小程序经 BODY 传输,按客户端 差异化配置有效期、Cookie 属性与来源白名单(支持子域通配符) - 适配登录/登出/在线用户/强制下线/客户端与租户策略/WebSocket 通知; AK/SK 第三方访问路径不参与 Refresh Token 处理 - 刷新/登出为租户无关认证请求:请求入口忽略残留租户头回落默认租户, 业务层按会话租户显式切换,普通租户无感刷新不会落默认租户 - 启动校验 Access/Refresh 密钥独立性,生产环境无默认密钥;限流默认 使用连接对端地址,仅显式配置可信代理后解析 XFF(配置错误 fail-safe) - 新增单元测试并在 CI 实际运行(auth-refresh/plugin-tenant/server 三模块 Surefire skip=false),Enforcer/Spotless/Checkstyle/SpotBugs 四道门禁全部通过 Assisted-by: DeepSeek Harness
luoqiz
force-pushed
the
feat-refresh-token
branch
from
September 19, 2026 04:17
dc94dd1 to
d4f5228
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
变更类型
破坏性变更
变更目的
为管理端 Web、App 与小程序提供可轮换的 Refresh Token 登录态:缩短 Access Token 生命周期,过期后由 Refresh Token 安全恢复原登录会话,并支持跨端会话统一失效(强退、顶下线、密码修改、租户/客户端禁用)。登录、刷新、登出、在线用户、强制下线与 WebSocket 实时通知全部纳入同一会话模型。
暂无关联 Issue。
功能设计
会话模型
continew-auth-refresh模块,集中管理 Refresh Token 签发、轮换、重放保护、会话查询与失效。sessionId.secret无状态格式:sessionId仅定位服务端会话,secret才是凭证;服务端只保存 secret 的 HMAC-SHA256 指纹,比对使用常量时间算法,数据库/Redis 泄露不直接暴露可用令牌。AUTH:REFRESH:V1:命名空间:SESSION(会话本体,含安全版本快照)、ROTATION(轮换结果快照)、LATEST(当前有效令牌指纹门禁)、REASON(失效原因,供客户端区分强退/顶下线/普通失效)、限流计数等。轮换与重放保护
LATEST指纹门禁原子完成。统一撤销与实时通知
RTopic广播 WebSocket 撤销通知与访问会话缓存失效,其它实例子秒级关闭该会话的实时连接。热路径性能
auth:access-session-invalid:{spring.application.name}),同一服务多副本共享、不同服务互不串扰,可显式覆盖为公共 Topic;提供开关,关闭即恢复逐请求实时校验。多客户端适配
__Host-前缀、Secure/SameSite/Path 配置),刷新请求由浏览器自动携带。http[s]://*.example.com子域通配符。/auth/refresh刷新、/auth/logout登出、在线用户查询、按 sessionId 强制下线、客户端/租户安全策略(密码修改后会话失效、租户禁用即失活)与 WebSocket 会话撤销通知;AK/SK 第三方访问路径不参与 Refresh Token 处理。租户隔离
sys_user行级隔离,不进入租户忽略白名单。安全基线
X-Forwarded-For;仅显式配置可信代理地址与跳数后才解析转发地址,配置错误为 fail-safe。配置项(application.yml
auth.refresh-token)secret${REFRESH_TOKEN_SECRET}cookie-name/cookie-path/cookie-secure/cookie-same-siterefresh_token/// false /Laxcookie-allowed-origins[]rotation-grace-period5ip-rate-limit/ip-rate-limit-period60/60session-rate-limit/session-rate-limit-period10/60trusted-proxy-addresses/trusted-proxy-hops[]/0access-session-cache-enabledtrueaccess-session-invalid-topicwebsocket-validation-interval60000测试情况
mvn -B -pl continew-server -am verify:四道门禁(Enforcer / Spotless / Checkstyle / SpotBugs)与全部单元测试通过,BUILD SUCCESS。continew-auth-refresh、continew-plugin-tenant、continew-server三个模块的单元测试实际运行(模块级覆盖 Surefireskip=false,根 POM 全局skip=true不变),覆盖:令牌轮换/重放、会话撤销、租户刷新边界、拦截器线程本地清理、在线用户、WebSocket 多标签页撤销与批量通知缓存、多连接 DAO 保留存活标签页等场景。continew-server排除依赖 MySQL/Redis 的 Spring 上下文测试(ContiNewAdminApplicationTests),交由 CI 完成最终上下文验证。Changelog
提交前确认
./mvnw verify四道门禁全部通过(完整上下文验证依赖本机 MySQL/Redis,本机已通过模块级 verify)Assisted-by: <智能体>标记破坏性变更与迁移
accessToken,客户端不得再读取旧token字段。sid;部署升级后,旧会话将被拒绝并要求重新登录。此行为是安全不变量(无sid的旧令牌无法与会话绑定,不得在升级后继续有效),属有意破坏性变更。sessionId为目标;登出/刷新统一由/auth/logout、/auth/refresh提供。发布协调与部署
必须与 continew-admin-ui#89 同时合并并同步发布。生产部署需配置两个独立认证密钥:
ACCESS_TOKEN_JWT_SECRET与REFRESH_TOKEN_SECRET。反向代理与真实客户端 IP(影响限流正确性)
刷新接口的限流默认使用 TCP 连接对端地址,不信任任何
X-Forwarded-For:auth.refresh-token.trusted-proxy-hops默认0、trusted-proxy-addresses默认为空 → 后端完全不解析 XFF,天然免疫伪造。ip-rate-limit默认 60 次/分钟将变成全站共享),必然大面积误伤:白名单取值可在后端容器内查看实际来源地址(
docker network inspect <网络名>),或临时打印request.getRemoteAddr()确认。本 PR 同时把
docker/nginx/conf/nginx.conf的 XFF 由$proxy_add_x_forwarded_for(追加)改为$remote_addr(覆盖),即在入口丢弃客户端自带的 XFF 头。原因:后端按「从右往左数hops个条目」解析,若hops配置错误——hops正确hops误配(多填)$proxy_add_x_forwarded_for(追加)$remote_addr(覆盖,本 PR 后)即覆盖语义下配置错误是 fail-safe 的,追加语义则会变成可绕过的防护缺口。