feat: backend core - auth, user, role, permission, device, webhook, monitoring, cache, repository, service, middleware, API handlers
This commit is contained in:
113
internal/auth/state.go
Normal file
113
internal/auth/state.go
Normal file
@@ -0,0 +1,113 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user