Files
opsx-licence/backend/internal/model/refresh_token.go
T
Logan.Li a01b89f942
CI / backend (push) Waiting to run
feat(auth): 记住登录 —— 刷新令牌持久化,不再在本机保存明文密码
- 后端:新增 refresh_token 模型与服务,登录签发 refresh token,支持静默续期与登出撤销
  (backend/internal/model/refresh_token.go, backend/internal/service/auth/refresh.go,
   auth_controller/auth_service/dto/router/jwt 配套改动)
- 前端:登录页改为「记住登录」(只持久化引导令牌与用户名,不落盘密码),401 自动刷新并重试原请求
  (stores/user.js, api/request.js, api/auth.js, main.js, Login.vue 配套改动)
- 部署:已在容器中验证运行(镜像构建于 2026-11-03 00:50,服务 healthy)
- 安全:仓库内无任何 .env/证书/密钥文件变更
2026-11-03 01:12:22 +08:00

29 lines
1.3 KiB
Go

package model
import "time"
// RefreshToken 刷新令牌(支撑「记住登录」,库内只存 SHA-256 摘要,明文仅返回一次)。
//
// 设计要点:
// 1. 一次性轮换:每次刷新都签发新令牌并撤销旧令牌,旧令牌的 RotatedTo 记录新令牌摘要;
// 2. 重放检测:已撤销的令牌再次出现 → 视为令牌泄漏,撤销该用户全部刷新令牌(强制重登);
// 3. 与 users.token_valid_after 配合:改密码后旧令牌的 refresh 也会被主动撤销。 // Logan.Li
type RefreshToken struct {
ID uint `json:"id" gorm:"primaryKey"`
UserID uint `json:"user_id" gorm:"index;not null"`
TokenHash string `json:"-" gorm:"size:64;uniqueIndex;not null"` // SHA-256(明文令牌) 十六进制
ExpiresAt time.Time `json:"expires_at" gorm:"index;not null"`
RevokedAt *time.Time `json:"revoked_at,omitempty"`
RotatedTo string `json:"-" gorm:"size:64"` // 轮换后的新令牌摘要(重放链追踪)
IP string `json:"ip" gorm:"size:64"`
UserAgent string `json:"user_agent" gorm:"size:255"`
LastUsed *time.Time `json:"last_used,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// TableName 指定表名,避开 GORM 复数推导 // Logan.Li
func (RefreshToken) TableName() string {
return "refresh_tokens"
}