package store import ( "errors" "log" "time" "github.com/bluele/gcache" "github.com/go-webauthn/webauthn/webauthn" "github.com/google/uuid" ) // WebAuthnSessionStore 使用 gcache 存储 WebAuthn 会话数据 type WebAuthnSessionStore struct { cache gcache.Cache } // NewWebAuthnSessionStore 创建一个新的会话存储实例 func NewWebAuthnSessionStore() *WebAuthnSessionStore { // 创建一个 LRU 缓存,最多存储 10000 个会话,每个会话有效期 5 分钟 gc := gcache.New(10000). LRU(). Expiration(5 * time.Minute). Build() return &WebAuthnSessionStore{cache: gc} } // GenerateSessionID 生成唯一的会话ID func GenerateSessionID() string { return uuid.NewString() } // SaveWebauthnSession 保存 WebAuthn 会话数据 func (s *WebAuthnSessionStore) SaveWebauthnSession(sessionID string, data *webauthn.SessionData) error { return s.cache.Set(sessionID, data) } // GetWebauthnSession 获取 WebAuthn 会话数据 func (s *WebAuthnSessionStore) GetWebauthnSession(sessionID string) (*webauthn.SessionData, error) { val, err := s.cache.Get(sessionID) if err != nil { if errors.Is(err, gcache.KeyNotFoundError) { return nil, errors.New("会话未找到或已过期") } return nil, err // 其他 gcache 错误 } sessionData, ok := val.(*webauthn.SessionData) if !ok { // 如果类型断言失败,说明缓存中存储了错误类型的数据 log.Printf("警告:会话存储中发现非预期的类型,Key: %s", sessionID) // 尝试删除无效数据 _ = s.cache.Remove(sessionID) return nil, errors.New("无效的会话数据类型") } return sessionData, nil } // DeleteWebauthnSession 删除 WebAuthn 会话数据 func (s *WebAuthnSessionStore) DeleteWebauthnSession(sessionID string) { s.cache.Remove(sessionID) } func (s *WebAuthnSessionStore) GetALL() map[any]any { return s.cache.GetALL(false) }