package token import ( "busniess-user-center/pkg/redis" "context" "crypto/sha1" "fmt" "strconv" "time" "github.com/pkg/errors" goRedis "github.com/redis/go-redis/v9" ) var ( errInvalidToken = errors.New("invalid token") USER_ID_TOKEN_RELATION = "user_id_token_relation" ) type TokenRefresher struct { expireIn time.Duration redis *redis.Redis } func NewTokenRefresher(redis *redis.Redis, expireIn time.Duration) *TokenRefresher { return &TokenRefresher{ expireIn: expireIn, redis: redis, } } func (tf *TokenRefresher) generateTokenKey(tokenID, token string) string { sha1Val := sha1.Sum([]byte(fmt.Sprintf("%s:%s", tokenID, token))) return fmt.Sprintf("loginbigdata:jwt:token:%x", sha1Val) } func (tf *TokenRefresher) Refresh(tokenID, token string) error { cacheKey := tf.generateTokenKey(tokenID, token) result, err := tf.redis.Client.Get(context.Background(), cacheKey).Result() if err != nil { if err == goRedis.Nil { return errInvalidToken } return errors.Wrapf(err, "failed to refresh token cause by redis. key: %s", cacheKey) } if result != "" { if err := tf.redis.Client.Expire(context.Background(), cacheKey, tf.expireIn).Err(); err != nil { return errors.Wrapf(err, "faild to refresh token case by expire redis. key: %s", cacheKey) } } return nil } func (tf *TokenRefresher) SetToken(tokenID, token, data string) error { cacheKey := tf.generateTokenKey(tokenID, token) _, err := tf.redis.Client.Set(context.Background(), cacheKey, data, tf.expireIn).Result() if err != nil { if err == goRedis.Nil { return errInvalidToken } return errors.Wrapf(err, "failed to set token cause by redis. key: %s", cacheKey) } return nil } func (tf *TokenRefresher) SetUseridTokenRelation(userid uint, token string) error { _, err := tf.redis.Client.HSet(context.Background(), USER_ID_TOKEN_RELATION, userid, token).Result() if err != nil { if err == goRedis.Nil { return errInvalidToken } return errors.Wrapf(err, "failed to SetUseridTokenRelation cause by redis. map:%s,key: %d", USER_ID_TOKEN_RELATION, userid) } return nil } func (tf *TokenRefresher) GetUserToken(userid uint) (string, error) { key := strconv.Itoa(int(userid)) token, err := tf.redis.Client.HGet(context.Background(), USER_ID_TOKEN_RELATION, key).Result() if err != nil { if err == goRedis.Nil { return token, errInvalidToken } return token, errors.Wrapf(err, "failed to GetUserToken cause by redis. map:%s,key: %d", USER_ID_TOKEN_RELATION, userid) } return token, nil } func (tf *TokenRefresher) DeleteToken(userId uint) error { key := strconv.Itoa(int(userId)) _, err := tf.redis.Client.HDel(context.Background(), USER_ID_TOKEN_RELATION, key).Result() if err != nil { if err == goRedis.Nil { return errInvalidToken } return errors.Wrapf(err, "failed to GetUserToken cause by redis. map:%s,key: %d", USER_ID_TOKEN_RELATION, userId) } return nil }