mirror of
https://github.com/truewhile/MeBox.git
synced 2026-11-12 19:34:24 +08:00
50 lines
1.8 KiB
Go
50 lines
1.8 KiB
Go
package model
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// AuthSession 是可撤销的设备认证会话。
|
|
//
|
|
// 会话与刷新令牌的关系是 1:N:一次登录创建一个会话,之后每次轮换刷新
|
|
// 令牌都继续归属同一会话。访问令牌通过 JWT 的 sid 字段引用会话,因此
|
|
// 服务端可以在 JWT 尚未过期时立即撤销某台设备的访问能力。
|
|
//
|
|
// 旧客户端没有会话关联(sid 为空),继续走既有兼容路径;本模型不强制
|
|
// 把历史刷新令牌绑定到任何设备。
|
|
type AuthSession struct {
|
|
ID string `gorm:"primaryKey;size:36" json:"id"`
|
|
UserID string `gorm:"index;size:36;not null" json:"user_id"`
|
|
DeviceID string `gorm:"index:idx_auth_session_device,priority:1;size:128;not null" json:"device_id"`
|
|
DeviceName string `gorm:"size:128" json:"device_name,omitempty"`
|
|
ClientName string `gorm:"size:64" json:"client_name,omitempty"`
|
|
ClientVersion string `gorm:"size:64" json:"client_version,omitempty"`
|
|
Revoked bool `gorm:"not null;default:false" json:"revoked"`
|
|
RevokedAt *time.Time `json:"revoked_at,omitempty"`
|
|
LastUsedAt time.Time `json:"last_used_at"`
|
|
ExpiresAt time.Time `gorm:"index" json:"expires_at"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
// BeforeCreate 生成 UUID 主键。
|
|
func (s *AuthSession) BeforeCreate(_ *gorm.DB) error {
|
|
if s.ID == "" {
|
|
s.ID = uuid.NewString()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// IsExpired 判断会话是否超过最长有效期。
|
|
func (s *AuthSession) IsExpired() bool {
|
|
return s != nil && !s.ExpiresAt.IsZero() && time.Now().After(s.ExpiresAt)
|
|
}
|
|
|
|
// IsValid 判断会话当前是否可继续使用。
|
|
func (s *AuthSession) IsValid() bool {
|
|
return s != nil && !s.Revoked && !s.IsExpired()
|
|
}
|