- Session 结构体新增 Status 字段,Create/Validate 同步状态 - AuthService.Login 移除封禁检查,允许封禁用户登录 - 新增 BannedWriteGuard 中间件,拦截 POST/PUT/DELETE 写操作 - 封禁用户自动签到跳过 - 所有需登录的 API 路由组应用 BannedWriteGuard - AdminService.UpdateUserStatus 保留 DestroyByUID 确保状态刷新
45 lines
1.3 KiB
Go
45 lines
1.3 KiB
Go
package session
|
||
|
||
import (
|
||
"crypto/rand"
|
||
"encoding/hex"
|
||
"time"
|
||
)
|
||
|
||
// Session 服务端会话,替代 JWT 无状态令牌
|
||
type Session struct {
|
||
ID string // 会话唯一标识(64 位 hex)
|
||
UserID uint // 用户 ID
|
||
Email string // 邮箱
|
||
Username string // 用户名
|
||
Avatar string // 头像 URL
|
||
Role string // 角色
|
||
Status string // 账号状态(active/banned/deleted/locked)
|
||
Exp int // 经验值(用于前端实时展示等级)
|
||
RememberMe bool // 是否持久化(决定 cookie maxAge)
|
||
IP string // 登录 IP
|
||
UserAgent string // 登录设备 User-Agent
|
||
Remark string // 用户备注(如"我的笔记本")
|
||
CreatedAt time.Time // 创建时间
|
||
LastAccess time.Time // 最后访问时间(滑动窗口)
|
||
}
|
||
|
||
// IsExpired 检查会话是否已过期
|
||
func (s *Session) IsExpired(idleTimeout time.Duration) bool {
|
||
return time.Since(s.LastAccess) > idleTimeout
|
||
}
|
||
|
||
// Touch 更新最后访问时间(续期)
|
||
func (s *Session) Touch() {
|
||
s.LastAccess = time.Now()
|
||
}
|
||
|
||
// NewID 生成 32 字节随机 hex 字符串作为会话 ID
|
||
func NewID() (string, error) {
|
||
b := make([]byte, 32)
|
||
if _, err := rand.Read(b); err != nil {
|
||
return "", err
|
||
}
|
||
return hex.EncodeToString(b), nil
|
||
}
|