添加 auth/session.go
This commit is contained in:
94
auth/session.go
Normal file
94
auth/session.go
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
// auth/session.go
|
||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/hex"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Session struct {
|
||||||
|
ID string
|
||||||
|
CreatedAt time.Time
|
||||||
|
ExpiresAt time.Time
|
||||||
|
LastSeen time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type SessionManager struct {
|
||||||
|
sessions sync.Map
|
||||||
|
timeout time.Duration
|
||||||
|
mu sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSessionManager(timeout time.Duration) *SessionManager {
|
||||||
|
sm := &SessionManager{
|
||||||
|
timeout: timeout,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动清理协程
|
||||||
|
go sm.cleanup()
|
||||||
|
|
||||||
|
return sm
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sm *SessionManager) Create(timeout time.Duration) string {
|
||||||
|
id := generateSecureToken()
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
|
sm.sessions.Store(id, &Session{
|
||||||
|
ID: id,
|
||||||
|
CreatedAt: now,
|
||||||
|
ExpiresAt: now.Add(timeout),
|
||||||
|
LastSeen: now,
|
||||||
|
})
|
||||||
|
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sm *SessionManager) Valid(id string) bool {
|
||||||
|
val, ok := sm.sessions.Load(id)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
session := val.(*Session)
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
|
if now.After(session.ExpiresAt) {
|
||||||
|
sm.sessions.Delete(id)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新最后活动时间和过期时间
|
||||||
|
session.LastSeen = now
|
||||||
|
session.ExpiresAt = now.Add(sm.timeout)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sm *SessionManager) Delete(id string) {
|
||||||
|
sm.sessions.Delete(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sm *SessionManager) cleanup() {
|
||||||
|
ticker := time.NewTicker(5 * time.Minute)
|
||||||
|
defer ticker.Stop()
|
||||||
|
|
||||||
|
for range ticker.C {
|
||||||
|
now := time.Now()
|
||||||
|
sm.sessions.Range(func(key, value interface{}) bool {
|
||||||
|
session := value.(*Session)
|
||||||
|
if now.After(session.ExpiresAt) {
|
||||||
|
sm.sessions.Delete(key)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateSecureToken() string {
|
||||||
|
b := make([]byte, 32)
|
||||||
|
rand.Read(b)
|
||||||
|
return hex.EncodeToString(b)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user