feat(auth): JWT 滑动续期 + 401 自动登出,修复长挂机莫名掉线
- 后端:JWT 有效期可配(JWT_EXPIRE_HOURS,默认 24h);令牌寿命过半时经 X-Renewed-Token 响应头滑动续期;新增 POST /api/auth/refresh 以数据库真实身份签发 - 前端 request 层:静默接管续期头并同步 localStorage;任何 401(登录/续期除外) 统一广播会话过期事件 - auth store:监听过期事件清理登录态并跳转 /login?expired=1(不再卡 403 页); 每 10 分钟定时续期,避免 WS 重连时令牌已过期 - 新增滑动续期单元测试(回签过期时间戳),go test -race 通过
This commit is contained in:
@@ -31,8 +31,9 @@ type DatabaseConfig struct {
|
||||
}
|
||||
|
||||
type JWTConfig struct {
|
||||
Secret string
|
||||
ExpireTime time.Duration
|
||||
Secret string
|
||||
ExpireTime time.Duration
|
||||
ExpireHours int
|
||||
}
|
||||
|
||||
// StorageConfig S3 兼容对象存储(MinIO / OSS / COS / S3 共用字段)
|
||||
@@ -70,10 +71,17 @@ func Load() *Config {
|
||||
Name: getEnv("DB_NAME", "kefu_cloud"),
|
||||
SSLMode: getEnv("DB_SSLMODE", "disable"),
|
||||
},
|
||||
JWT: JWTConfig{
|
||||
Secret: getEnv("JWT_SECRET", "kefu-cloud-secret-key"),
|
||||
ExpireTime: 24 * time.Hour,
|
||||
},
|
||||
JWT: func() JWTConfig {
|
||||
hours := getEnvInt("JWT_EXPIRE_HOURS", 24)
|
||||
if hours <= 0 {
|
||||
hours = 24
|
||||
}
|
||||
return JWTConfig{
|
||||
Secret: getEnv("JWT_SECRET", "kefu-cloud-secret-key"),
|
||||
ExpireTime: time.Duration(hours) * time.Hour,
|
||||
ExpireHours: hours,
|
||||
}
|
||||
}(),
|
||||
Storage: StorageConfig{
|
||||
// 默认映射宿主机 9100→容器 9000,避免与其它项目 MinIO 冲突
|
||||
Endpoint: getEnv("STORAGE_ENDPOINT", "localhost:9100"),
|
||||
|
||||
Reference in New Issue
Block a user