refresh_token_cache.go 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package service
  2. import (
  3. "context"
  4. "errors"
  5. "time"
  6. )
  7. // ErrRefreshTokenNotFound is returned when a refresh token is not found in cache.
  8. // This is used to abstract away the underlying cache implementation (e.g., redis.Nil).
  9. var ErrRefreshTokenNotFound = errors.New("refresh token not found")
  10. // RefreshTokenData 存储在Redis中的Refresh Token数据
  11. type RefreshTokenData struct {
  12. UserID int64 `json:"user_id"`
  13. TokenVersion int64 `json:"token_version"` // 用于检测密码更改后的Token失效
  14. FamilyID string `json:"family_id"` // Token家族ID,用于防重放攻击
  15. BindingHash string `json:"binding_hash,omitempty"` // 会话指纹哈希(IP+UA),会话绑定开启时校验
  16. CreatedAt time.Time `json:"created_at"`
  17. ExpiresAt time.Time `json:"expires_at"`
  18. }
  19. // RefreshTokenCache 管理Refresh Token的Redis缓存
  20. // 用于JWT Token刷新机制,支持Token轮转和防重放攻击
  21. //
  22. // Key 格式:
  23. // - refresh_token:{token_hash} -> RefreshTokenData (JSON)
  24. // - user_refresh_tokens:{user_id} -> Set<token_hash>
  25. // - token_family:{family_id} -> Set<token_hash>
  26. type RefreshTokenCache interface {
  27. // StoreRefreshToken 存储Refresh Token
  28. // tokenHash: Token的SHA256哈希值(不存储原始Token)
  29. // data: Token关联的数据
  30. // ttl: Token过期时间
  31. StoreRefreshToken(ctx context.Context, tokenHash string, data *RefreshTokenData, ttl time.Duration) error
  32. // GetRefreshToken 获取Refresh Token数据
  33. // 返回 (data, nil) 如果Token存在
  34. // 返回 (nil, ErrRefreshTokenNotFound) 如果Token不存在
  35. // 返回 (nil, err) 如果发生其他错误
  36. GetRefreshToken(ctx context.Context, tokenHash string) (*RefreshTokenData, error)
  37. // DeleteRefreshToken 删除单个Refresh Token
  38. // 用于Token轮转时使旧Token失效
  39. DeleteRefreshToken(ctx context.Context, tokenHash string) error
  40. // DeleteUserRefreshTokens 删除用户的所有Refresh Token
  41. // 用于密码更改或用户主动登出所有设备
  42. DeleteUserRefreshTokens(ctx context.Context, userID int64) error
  43. // DeleteTokenFamily 删除整个Token家族
  44. // 用于检测到Token重放攻击时,撤销整个会话链
  45. DeleteTokenFamily(ctx context.Context, familyID string) error
  46. // AddToUserTokenSet 将Token添加到用户的Token集合
  47. // 用于跟踪用户的所有活跃Refresh Token
  48. AddToUserTokenSet(ctx context.Context, userID int64, tokenHash string, ttl time.Duration) error
  49. // AddToFamilyTokenSet 将Token添加到家族Token集合
  50. // 用于跟踪同一登录会话的所有Token
  51. AddToFamilyTokenSet(ctx context.Context, familyID string, tokenHash string, ttl time.Duration) error
  52. // GetUserTokenHashes 获取用户的所有Token哈希
  53. // 用于批量删除用户Token
  54. GetUserTokenHashes(ctx context.Context, userID int64) ([]string, error)
  55. // GetFamilyTokenHashes 获取家族的所有Token哈希
  56. // 用于批量删除家族Token
  57. GetFamilyTokenHashes(ctx context.Context, familyID string) ([]string, error)
  58. // IsTokenInFamily 检查Token是否属于指定家族
  59. // 用于验证Token家族关系
  60. IsTokenInFamily(ctx context.Context, familyID string, tokenHash string) (bool, error)
  61. }