token_store.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. package utils
  2. import (
  3. "errors"
  4. "log"
  5. "strings"
  6. "sync"
  7. "time"
  8. "git.qianqiusoft.com/qianqiusoft/light-apiengine/config"
  9. "git.qianqiusoft.com/qianqiusoft/light-apiengine/entitys"
  10. "git.qianqiusoft.com/qianqiusoft/light-apiengine/logs"
  11. )
  12. type TokenStore interface {
  13. Get(string) *entitys.Token
  14. Set(string, *entitys.Token)
  15. Remove(key string)
  16. Refresh(key string)
  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. //log.Println(key, "获取Token:", val.AccessToken, val.RefreshToken, val.LoginID)
  40. return val
  41. }
  42. return nil
  43. }
  44. func (t *MemoryStore) Set(key string, v *entitys.Token) {
  45. t.lock.Lock()
  46. defer t.lock.Unlock()
  47. if val, ok := t.tokens[key]; !ok {
  48. t.tokens[key] = v
  49. } else if val != v {
  50. t.tokens[key] = v
  51. }
  52. log.Println(key, "添加Token:", v.AccessToken, v.RefreshToken, v.LoginID)
  53. }
  54. func (t *MemoryStore) Remove(key string) {
  55. t.lock.Lock()
  56. defer t.lock.Unlock()
  57. delete(t.tokens, key)
  58. log.Println(key, "删除Key")
  59. }
  60. func (t *MemoryStore) Refresh(key string) {
  61. t.lock.Lock()
  62. defer t.lock.Unlock()
  63. val, ok := t.tokens[key]
  64. if ok {
  65. val.TimeStamp = uint64(time.Now().UnixNano())
  66. }
  67. }
  68. func (t *MemoryStore) startTokenCheckProcess() {
  69. autoRefresh := config.AppConfig.AutoRefresh
  70. if !autoRefresh {
  71. return
  72. }
  73. var duration time.Duration = time.Second * 3600
  74. t1 := time.NewTicker(duration)
  75. for {
  76. select {
  77. case <-t1.C:
  78. t.lock.Lock()
  79. keys := []string{}
  80. for k, v := range t.tokens {
  81. timestampt := time.Unix(int64(v.TimeStamp), 0)
  82. subval := time.Now().Sub(timestampt)
  83. if subval.Seconds() < 0 || subval.Seconds() > 3600 {
  84. keys = append(keys, k)
  85. }
  86. }
  87. for _, k := range keys {
  88. delete(t.tokens, k)
  89. }
  90. t.lock.Unlock()
  91. }
  92. }
  93. }
  94. func Validate(accessToken, loginId string, domain string) (*entitys.Token, error) {
  95. token := globalTokenStore.Get(loginId + domain)
  96. if token != nil {
  97. if strings.EqualFold(token.AccessToken, accessToken) {
  98. logs.Info("get the token ", accessToken, " of id ", loginId+domain)
  99. globalTokenStore.Refresh(loginId + domain)
  100. return token, nil
  101. } else {
  102. logs.Error(token.AccessToken, "is not equal to", accessToken)
  103. return token, errors.New(token.AccessToken + " is not equal to " + accessToken)
  104. }
  105. } else {
  106. logs.Error("can not get the token of", loginId+domain)
  107. return token, errors.New("can not get the token of " + loginId + domain)
  108. }
  109. }
  110. func TokenValidate(token string) (*entitys.Token, error) {
  111. user := globalTokenStore.Get(token)
  112. if strings.EqualFold(user.AccessToken, token) {
  113. logs.Info("get the token ", token, " of id ")
  114. globalTokenStore.Refresh(token)
  115. return user, nil
  116. } else {
  117. logs.Error(user.AccessToken, "is not equal to", token)
  118. return user, errors.New(user.AccessToken + " is not equal to " + token)
  119. }
  120. }