token_store.go 2.9 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)
  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) {
  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. }
  64. func (t *MemoryStore) startTokenCheckProcess() {
  65. autoRefresh := config.AppConfig.AutoRefresh
  66. if !autoRefresh {
  67. return
  68. }
  69. var duration time.Duration = time.Second * 3600
  70. t1 := time.NewTicker(duration)
  71. for {
  72. select {
  73. case <-t1.C:
  74. t.lock.Lock()
  75. keys := []string{}
  76. for k, v := range t.tokens {
  77. timestampt := time.Unix(int64(v.TimeStamp), 0)
  78. subval := time.Now().Sub(timestampt)
  79. if subval.Seconds() < 0 || subval.Seconds() > 3600 {
  80. keys = append(keys, k)
  81. }
  82. }
  83. for _, k := range keys {
  84. delete(t.tokens, k)
  85. }
  86. t.lock.Unlock()
  87. }
  88. }
  89. }
  90. func Validate(accessToken, loginId string, domain string) (*entitys.Token, error) {
  91. token := globalTokenStore.Get(loginId + domain)
  92. if token != nil {
  93. if strings.EqualFold(token.AccessToken, accessToken) {
  94. globalTokenStore.Refresh(loginId + domain)
  95. return token, nil
  96. } else {
  97. logs.Error(token.AccessToken, "is not equal to", accessToken)
  98. return token, errors.New(token.AccessToken + " is not equal to " + accessToken)
  99. }
  100. } else {
  101. logs.Error("can not get the token of", loginId+domain)
  102. return token, errors.New("can not get the token of " + loginId + domain)
  103. }
  104. }
  105. func TokenValidate(token string) (*entitys.Token, error) {
  106. tokenRaw := globalTokenStore.Get(token)
  107. if strings.EqualFold(tokenRaw.AccessToken, token) {
  108. globalTokenStore.Refresh(token)
  109. return tokenRaw, nil
  110. } else {
  111. logs.Error(tokenRaw.AccessToken, "is not equal to", token)
  112. return tokenRaw, errors.New(tokenRaw.AccessToken + " is not equal to " + token)
  113. }
  114. }