busniess-user-center/pkg/utils/token/token.go

97 lines
2.5 KiB
Go

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
}