package utils import ( "errors" "git.qianqiusoft.com/qianqiusoft/light-apiengine/config" "git.qianqiusoft.com/qianqiusoft/light-apiengine/entitys" "git.qianqiusoft.com/qianqiusoft/light-apiengine/logs" "log" "strings" "sync" "time" ) type TokenStore struct { name string lock *sync.RWMutex tokens map[string]*entitys.Token } var globalTokenStore *TokenStore = nil func init() { globalTokenStore = &TokenStore{name: "sso", lock: new(sync.RWMutex), tokens: make(map[string]*entitys.Token)} go globalTokenStore.startTokenCheckProcess() } func GetGlobalTokenStore() *TokenStore { return globalTokenStore } func (t *TokenStore) Get(key string) *entitys.Token { t.lock.RLock() defer t.lock.RUnlock() if val, ok := t.tokens[key]; ok { //log.Println(key, "获取Token:", val.AccessToken, val.RefreshToken, val.LoginID) return val } return nil } func (t *TokenStore) Set(key string, v *entitys.Token) { t.lock.Lock() defer t.lock.Unlock() if val, ok := t.tokens[key]; !ok { t.tokens[key] = v } else if val != v { t.tokens[key] = v } log.Println(key, "添加Token:", v.AccessToken, v.RefreshToken, v.LoginID) } func (t *TokenStore) Remove(key string) { t.lock.Lock() defer t.lock.Unlock() delete(t.tokens, key) log.Println(key, "删除Key") } func (t *TokenStore) Refresh(key string) { t.lock.Lock() defer t.lock.Unlock() val, ok := t.tokens[key] if ok { val.TimeStamp = uint64(time.Now().UnixNano()) } } func (t *TokenStore) startTokenCheckProcess() { autoRefresh := config.AppConfig.AutoRefresh if !autoRefresh { return } var duration time.Duration = time.Second * 3600 t1 := time.NewTicker(duration) for { select { case <-t1.C: t.lock.Lock() keys := []string{} for k, v := range t.tokens { timestampt := time.Unix(int64(v.TimeStamp), 0) subval := time.Now().Sub(timestampt) if subval.Seconds() < 0 || subval.Seconds() > 3600 { keys = append(keys, k) } } for _, k := range keys { delete(t.tokens, k) } t.lock.Unlock() } } } func Validate(accessToken, loginId string, domain string) (*entitys.Token, error) { token := globalTokenStore.Get(loginId + domain) if token != nil { if strings.EqualFold(token.AccessToken, accessToken) { logs.Info("get the token ", accessToken, " of id ", loginId+domain) globalTokenStore.Refresh(loginId + domain) return token, nil } else { logs.Error(token.AccessToken, "is not equal to", accessToken) return token, errors.New(token.AccessToken + " is not equal to " + accessToken) } } else { logs.Error("can not get the token of", loginId+domain) return token, errors.New("can not get the token of " + loginId + domain) } } func TokenValidate(token string) (*entitys.Token, error) { user := globalTokenStore.Get(token) if strings.EqualFold(user.AccessToken, token) { logs.Info("get the token ", token, " of id ") globalTokenStore.Refresh(token) return user, nil } else { logs.Error(user.AccessToken, "is not equal to", token) return user, errors.New(user.AccessToken + " is not equal to " + token) } } //func ValidateApp(appName, accessToken, timestamp, signature string) (*entitys.Token, error) { // fmt.Println(appName, accessToken, timestamp, signature) // if appName == "" || timestamp == "" || accessToken == "" || signature == "" { // return nil, errors.New("some param is empty") // } // // // check time out // timestampi, err := strconv.ParseInt(timestamp, 10, 64) // if err != nil { // return nil, err // } // // timestampt := time.Unix(timestampi, 0) // subval := time.Now().Sub(timestampt) // // period := config.ApiConfig.GetInt("period") // // if subval.Seconds() < 0 || subval.Seconds() > float64(period) { // return nil, errors.New("the request is out of time") // } // // end of check time out // // // validate accessToken // appInfo, err := appManager.GetUamAppByName(appName) // if err != nil { // return nil, err // } // fmt.Println("----------------------------3") // // signatureOrg := appInfo.Name + "." + timestamp + "." + appInfo.Token // generate the // hs := md5.New() // hs.Write([]byte(signatureOrg)) // signatureStr := base64.StdEncoding.EncodeToString(hs.Sum(nil)) // // fmt.Println("-----------------signatureStr", signatureStr) // // if signatureStr != signature { // return nil, errors.New("the signature is invalid") // } // fmt.Println("----------------------------2") // // str := appInfo.Token + "." + timestamp // generate accesstoken // hs = md5.New() // hs.Write([]byte(str)) // md5Str := base64.StdEncoding.EncodeToString(hs.Sum(nil)) // if accessToken != md5Str { // return nil, errors.New("token is invalid") // } // // fmt.Println("----------------------------1") // // rt := &entitys.Token{} // rt.AccessToken = utils.GenerateToken(accessToken + "." + timestamp) // rt.Result = 0 // rt.UserId = appInfo.Id // rt.LoginID = appInfo.Name // rt.TimeStamp = uint64(timestampi) // return rt, nil //}