Files
Nexus/docs/changelog/2026-06-07-refresh-token-redis-mysql-dual-store.md
T
Nexus Agent 05006cb5df feat(auth): refresh token 先 Redis 后 MySQL 双写
登录 30 天会话 hash 持久化到 admin_refresh_tokens;启动从 MySQL 回填 Redis,
Redis 重启后会话仍可 refresh。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-07 21:56:56 +08:00

1.6 KiB
Raw Blame History

2026-06-07 — 登录 Refresh Token Redis + MySQL 双写

摘要

30 天登录会话的 refresh token 改为 先写 Redis、再写 MySQLAPI 启动时从 MySQL 回填 RedisRedis 重启/flush 后会话不丢失。

动机

此前 refresh token 仅存 Redis Setrefresh_tokens:{admin_id}),Redis 重载或 flush 后 HttpOnly Cookie 仍在但服务端认不出,用户被迫重新登录。

变更

文件 说明
server/domain/models/__init__.py admin_refresh_tokenstoken_hash + expires_at
server/infrastructure/database/refresh_token_repo.py MySQL CRUD / rotate / 按 admin 清理
server/application/services/auth_service.py 双写、校验 MySQL 回退、rotate 双端
server/application/services/refresh_token_hydration.py 启动 hydration + 清理过期行
server/main.py init_redis 后 hydration
server/api/dependencies.py 注入 refresh_token_repo
server/api/auth.py 改密走 _delete_all_refresh_tokens 双端清理
server/infrastructure/database/migrations.py CREATE TABLE 迁移
tests/test_refresh_token_persistence.py 双写 / MySQL 回退 / 双删

配置

  • 有效期仍由 JWT_REFRESH_TOKEN_EXPIRE_DAYS(默认 30)控制
  • Access Token 仍约 60 分钟,靠 refresh 续期

迁移 / 重启

需重启 API;新表自动 create_all + schema migration。

验证

pytest tests/test_refresh_token_persistence.py tests/test_auth_refresh_reuse.py -q

登录 → 重启 Redis → 刷新页面应仍可续期(hydration + MySQL 回退)。