token_store.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. package utils
  2. import (
  3. "errors"
  4. "git.qianqiusoft.com/qianqiusoft/light-apiengine/config"
  5. "git.qianqiusoft.com/qianqiusoft/light-apiengine/entitys"
  6. "git.qianqiusoft.com/qianqiusoft/light-apiengine/logs"
  7. "log"
  8. "strings"
  9. "sync"
  10. "time"
  11. )
  12. type TokenStore struct {
  13. name string
  14. lock *sync.RWMutex
  15. tokens map[string]*entitys.Token
  16. }
  17. var globalTokenStore *TokenStore = nil
  18. func init() {
  19. globalTokenStore = &TokenStore{name: "sso", lock: new(sync.RWMutex), tokens: make(map[string]*entitys.Token)}
  20. go globalTokenStore.startTokenCheckProcess()
  21. }
  22. func GetGlobalTokenStore() *TokenStore {
  23. return globalTokenStore
  24. }
  25. func (t *TokenStore) Get(key string) *entitys.Token {
  26. t.lock.RLock()
  27. defer t.lock.RUnlock()
  28. if val, ok := t.tokens[key]; ok {
  29. //log.Println(key, "获取Token:", val.AccessToken, val.RefreshToken, val.LoginID)
  30. return val
  31. }
  32. return nil
  33. }
  34. func (t *TokenStore) Set(key string, v *entitys.Token) {
  35. t.lock.Lock()
  36. defer t.lock.Unlock()
  37. if val, ok := t.tokens[key]; !ok {
  38. t.tokens[key] = v
  39. } else if val != v {
  40. t.tokens[key] = v
  41. }
  42. log.Println(key, "添加Token:", v.AccessToken, v.RefreshToken, v.LoginID)
  43. }
  44. func (t *TokenStore) Remove(key string) {
  45. t.lock.Lock()
  46. defer t.lock.Unlock()
  47. delete(t.tokens, key)
  48. log.Println(key, "删除Key")
  49. }
  50. func (t *TokenStore) Refresh(key string) {
  51. t.lock.Lock()
  52. defer t.lock.Unlock()
  53. val, ok := t.tokens[key]
  54. if ok {
  55. val.TimeStamp = uint64(time.Now().UnixNano())
  56. }
  57. }
  58. func (t *TokenStore) startTokenCheckProcess() {
  59. autoRefresh := config.AppConfig.AutoRefresh
  60. if !autoRefresh {
  61. return
  62. }
  63. var duration time.Duration = time.Second * 3600
  64. t1 := time.NewTicker(duration)
  65. for {
  66. select {
  67. case <-t1.C:
  68. t.lock.Lock()
  69. keys := []string{}
  70. for k, v := range t.tokens {
  71. timestampt := time.Unix(int64(v.TimeStamp), 0)
  72. subval := time.Now().Sub(timestampt)
  73. if subval.Seconds() < 0 || subval.Seconds() > 3600 {
  74. keys = append(keys, k)
  75. }
  76. }
  77. for _, k := range keys {
  78. delete(t.tokens, k)
  79. }
  80. t.lock.Unlock()
  81. }
  82. }
  83. }
  84. func Validate(accessToken, loginId string, domain string) (*entitys.Token, error) {
  85. token := globalTokenStore.Get(loginId + domain)
  86. if token != nil {
  87. if strings.EqualFold(token.AccessToken, accessToken) {
  88. logs.Info("get the token ", accessToken, " of id ", loginId+domain)
  89. globalTokenStore.Refresh(loginId + domain)
  90. return token, nil
  91. } else {
  92. logs.Error(token.AccessToken, "is not equal to", accessToken)
  93. return token, errors.New(token.AccessToken + " is not equal to " + accessToken)
  94. }
  95. } else {
  96. logs.Error("can not get the token of", loginId+domain)
  97. return token, errors.New("can not get the token of " + loginId + domain)
  98. }
  99. }
  100. func TokenValidate(token string) (*entitys.Token, error) {
  101. user := globalTokenStore.Get(token)
  102. if strings.EqualFold(user.AccessToken, token) {
  103. logs.Info("get the token ", token, " of id ")
  104. globalTokenStore.Refresh(token)
  105. return user, nil
  106. } else {
  107. logs.Error(user.AccessToken, "is not equal to", token)
  108. return user, errors.New(user.AccessToken + " is not equal to " + token)
  109. }
  110. }
  111. //func ValidateApp(appName, accessToken, timestamp, signature string) (*entitys.Token, error) {
  112. // fmt.Println(appName, accessToken, timestamp, signature)
  113. // if appName == "" || timestamp == "" || accessToken == "" || signature == "" {
  114. // return nil, errors.New("some param is empty")
  115. // }
  116. //
  117. // // check time out
  118. // timestampi, err := strconv.ParseInt(timestamp, 10, 64)
  119. // if err != nil {
  120. // return nil, err
  121. // }
  122. //
  123. // timestampt := time.Unix(timestampi, 0)
  124. // subval := time.Now().Sub(timestampt)
  125. //
  126. // period := config.ApiConfig.GetInt("period")
  127. //
  128. // if subval.Seconds() < 0 || subval.Seconds() > float64(period) {
  129. // return nil, errors.New("the request is out of time")
  130. // }
  131. // // end of check time out
  132. //
  133. // // validate accessToken
  134. // appInfo, err := appManager.GetUamAppByName(appName)
  135. // if err != nil {
  136. // return nil, err
  137. // }
  138. // fmt.Println("----------------------------3")
  139. //
  140. // signatureOrg := appInfo.Name + "." + timestamp + "." + appInfo.Token // generate the
  141. // hs := md5.New()
  142. // hs.Write([]byte(signatureOrg))
  143. // signatureStr := base64.StdEncoding.EncodeToString(hs.Sum(nil))
  144. //
  145. // fmt.Println("-----------------signatureStr", signatureStr)
  146. //
  147. // if signatureStr != signature {
  148. // return nil, errors.New("the signature is invalid")
  149. // }
  150. // fmt.Println("----------------------------2")
  151. //
  152. // str := appInfo.Token + "." + timestamp // generate accesstoken
  153. // hs = md5.New()
  154. // hs.Write([]byte(str))
  155. // md5Str := base64.StdEncoding.EncodeToString(hs.Sum(nil))
  156. // if accessToken != md5Str {
  157. // return nil, errors.New("token is invalid")
  158. // }
  159. //
  160. // fmt.Println("----------------------------1")
  161. //
  162. // rt := &entitys.Token{}
  163. // rt.AccessToken = utils.GenerateToken(accessToken + "." + timestamp)
  164. // rt.Result = 0
  165. // rt.UserId = appInfo.Id
  166. // rt.LoginID = appInfo.Name
  167. // rt.TimeStamp = uint64(timestampi)
  168. // return rt, nil
  169. //}