token_store.go 3.2 KB

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