token_store.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package utils
  2. import (
  3. "errors"
  4. "strings"
  5. "sync"
  6. "time"
  7. "git.qianqiusoft.com/qianqiusoft/light-apiengine/config"
  8. "git.qianqiusoft.com/qianqiusoft/light-apiengine/entitys"
  9. "git.qianqiusoft.com/qianqiusoft/light-apiengine/logs"
  10. )
  11. type TokenStore interface {
  12. Get(string) *entitys.Token
  13. Set(string, *entitys.Token)
  14. Remove(key string)
  15. Refresh(key string) *entitys.Token
  16. }
  17. type MemoryStore struct {
  18. name string
  19. lock *sync.RWMutex
  20. tokens map[string]*entitys.Token
  21. }
  22. var globalTokenStore TokenStore
  23. func init() {
  24. memoryStore := &MemoryStore{name: "sso", lock: new(sync.RWMutex), tokens: make(map[string]*entitys.Token)}
  25. globalTokenStore = memoryStore
  26. go memoryStore.startTokenCheckProcess()
  27. }
  28. func GetGlobalTokenStore() TokenStore {
  29. return globalTokenStore
  30. }
  31. func SetGlobalTokenStore(store TokenStore) {
  32. globalTokenStore = store
  33. }
  34. func (t *MemoryStore) Get(key string) *entitys.Token {
  35. t.lock.RLock()
  36. defer t.lock.RUnlock()
  37. if val, ok := t.tokens[key]; ok {
  38. return val
  39. }
  40. return nil
  41. }
  42. func (t *MemoryStore) Set(key string, v *entitys.Token) {
  43. t.lock.Lock()
  44. defer t.lock.Unlock()
  45. if val, ok := t.tokens[key]; !ok {
  46. t.tokens[key] = v
  47. } else if val != v {
  48. t.tokens[key] = v
  49. }
  50. }
  51. func (t *MemoryStore) Remove(key string) {
  52. t.lock.Lock()
  53. defer t.lock.Unlock()
  54. delete(t.tokens, key)
  55. }
  56. func (t *MemoryStore) Refresh(key string) *entitys.Token {
  57. t.lock.Lock()
  58. defer t.lock.Unlock()
  59. val, ok := t.tokens[key]
  60. if ok {
  61. val.TimeStamp = uint64(time.Now().UnixNano())
  62. }
  63. return val
  64. }
  65. func (t *MemoryStore) startTokenCheckProcess() {
  66. autoRefresh := config.AppConfig.AutoRefresh
  67. if !autoRefresh {
  68. return
  69. }
  70. var duration time.Duration = time.Second * 3600
  71. t1 := time.NewTicker(duration)
  72. for {
  73. select {
  74. case <-t1.C:
  75. t.lock.Lock()
  76. keys := []string{}
  77. for k, v := range t.tokens {
  78. timestampt := time.Unix(int64(v.TimeStamp), 0)
  79. subval := time.Now().Sub(timestampt)
  80. if subval.Seconds() < 0 || subval.Seconds() > 3600 {
  81. keys = append(keys, k)
  82. }
  83. }
  84. for _, k := range keys {
  85. delete(t.tokens, k)
  86. }
  87. t.lock.Unlock()
  88. }
  89. }
  90. }
  91. func Validate(accessToken, loginId string, domain string) (*entitys.Token, error) {
  92. token := globalTokenStore.Get(loginId + domain)
  93. if token != nil {
  94. if strings.EqualFold(token.AccessToken, accessToken) {
  95. globalTokenStore.Refresh(loginId + domain)
  96. return token, nil
  97. } else {
  98. logs.Error(token.AccessToken, "is not equal to", accessToken)
  99. return token, errors.New(token.AccessToken + " is not equal to " + accessToken)
  100. }
  101. } else {
  102. logs.Error("can not get the token of", loginId+domain)
  103. return token, errors.New("can not get the token of " + loginId + domain)
  104. }
  105. }
  106. func TokenValidate(token string) (*entitys.Token, error) {
  107. tokenRaw := globalTokenStore.Get(token)
  108. if strings.EqualFold(tokenRaw.AccessToken, token) {
  109. globalTokenStore.Refresh(token)
  110. return tokenRaw, nil
  111. } else {
  112. logs.Error(tokenRaw.AccessToken, "is not equal to", token)
  113. return tokenRaw, errors.New(tokenRaw.AccessToken + " is not equal to " + token)
  114. }
  115. }