Files
user-system/internal/auth/state.go

114 lines
2.4 KiB
Go
Raw Normal View History

package auth
import (
"sync"
"time"
)
// StateManager OAuth状态管理器
type StateManager struct {
states map[string]time.Time
mu sync.RWMutex
ttl time.Duration
}
var (
// 全局状态管理器
stateManager = &StateManager{
states: make(map[string]time.Time),
ttl: 10 * time.Minute, // 10分钟过期
}
)
// Note: GenerateState and ValidateState are defined in oauth_utils.go
// to avoid duplication, please use those implementations
// Store 存储state
func (sm *StateManager) Store(state string) {
sm.mu.Lock()
defer sm.mu.Unlock()
sm.states[state] = time.Now()
}
// Validate 验证state
func (sm *StateManager) Validate(state string) bool {
sm.mu.RLock()
defer sm.mu.RUnlock()
expiredAt, exists := sm.states[state]
if !exists {
return false
}
// 检查是否过期
return time.Now().Before(expiredAt.Add(sm.ttl))
}
// Delete 删除state使用后删除
func (sm *StateManager) Delete(state string) {
sm.mu.Lock()
defer sm.mu.Unlock()
delete(sm.states, state)
}
// Cleanup 清理过期的state
func (sm *StateManager) Cleanup() {
sm.mu.Lock()
defer sm.mu.Unlock()
now := time.Now()
for state, expiredAt := range sm.states {
if now.After(expiredAt.Add(sm.ttl)) {
delete(sm.states, state)
}
}
}
// StartCleanupRoutine 启动定期清理goroutine
// stop channel 关闭时清理goroutine将优雅退出
func (sm *StateManager) StartCleanupRoutine(stop <-chan struct{}) {
ticker := time.NewTicker(5 * time.Minute)
go func() {
for {
select {
case <-ticker.C:
sm.Cleanup()
case <-stop:
ticker.Stop()
return
}
}
}()
}
// CleanupRoutineManager 管理清理goroutine的生命周期
type CleanupRoutineManager struct {
stopChan chan struct{}
}
var cleanupRoutineManager *CleanupRoutineManager
// StartCleanupRoutineWithManager 使用管理器启动清理goroutine
func StartCleanupRoutineWithManager() {
if cleanupRoutineManager != nil {
return // 已经启动
}
cleanupRoutineManager = &CleanupRoutineManager{
stopChan: make(chan struct{}),
}
stateManager.StartCleanupRoutine(cleanupRoutineManager.stopChan)
}
// StopCleanupRoutine 停止清理goroutine用于优雅关闭
func StopCleanupRoutine() {
if cleanupRoutineManager != nil {
close(cleanupRoutineManager.stopChan)
cleanupRoutineManager = nil
}
}
// GetStateManager 获取全局状态管理器
func GetStateManager() *StateManager {
return stateManager
}