fix: 会话时效30天 + 多设备同时登录
- access token 从 30 分钟延长到 30 天 - refresh token 从 7 天延长到 30 天 - refresh token 从 MySQL 单字段改为 Redis Set 存储,支持多设备同时登录 - 单设备退出不再踢掉其他设备(只删自己的 Redis hash) - 改密码/禁用 TOTP 仍会让所有设备掉线(token_version 递增) - 移除 reuse 误杀逻辑:版本不匹配只拒绝当前 token,不惩罚其他设备 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+9
-3
@@ -289,12 +289,18 @@ async def change_password(
|
||||
new_hash = bcrypt.hashpw(payload.new_password.encode(), bcrypt.gensalt()).decode()
|
||||
|
||||
current_admin.password_hash = new_hash
|
||||
# Security: invalidate all existing sessions (refresh tokens + JWT updated_at check)
|
||||
# Security: invalidate all existing sessions (refresh tokens + JWT token_version)
|
||||
current_admin.token_version += 1
|
||||
current_admin.jwt_refresh_token = None
|
||||
current_admin.jwt_token_expires = None
|
||||
await admin_repo.update(current_admin)
|
||||
|
||||
# Clear all refresh tokens from Redis (all devices logged out)
|
||||
try:
|
||||
from server.infrastructure.redis.client import get_redis
|
||||
redis = get_redis()
|
||||
await redis.delete(f"refresh_tokens:{admin.id}")
|
||||
except Exception:
|
||||
logger.warning(f"Failed to clear refresh tokens from Redis for admin {admin.id}", exc_info=True)
|
||||
|
||||
# Audit log with client IP
|
||||
ip_address = request.client.host if request.client else ""
|
||||
audit_repo = AuditLogRepositoryImpl(db)
|
||||
|
||||
Reference in New Issue
Block a user