package jwt import ( "errors" "fmt" jwt "github.com/golang-jwt/jwt/v4" "github.com/spf13/cast" "github.com/zeromicro/go-zero/rest/token" "net/http" "time" ) type Config struct { AccessSecret string `json:",default=ac2d27613e131be6286c0eb17139293d"` AccessExpire time.Duration `json:",default=24h"` } type TokenBuilder struct { config Config } func NewTokenBuilder(config Config) *TokenBuilder { return &TokenBuilder{config: config} } // GenerateToken 生成token func (b *TokenBuilder) GenerateToken(kvs map[string]any) (string, int64, error) { // 创建一个新的 Token tok := jwt.New(jwt.SigningMethodHS256) // 设置 Token 的声明(Payload) claims := tok.Claims.(jwt.MapClaims) for k, v := range kvs { claims[k] = v } expiredAt := time.Now().Add(b.config.AccessExpire).Unix() claims["exp"] = expiredAt // 设置过期时间 // 使用密钥签名 Token tkStr, err := tok.SignedString([]byte(b.config.AccessSecret)) return tkStr, expiredAt, err } func (b *TokenBuilder) ParseUidFromToken(tokenStr string) (int, int64, error) { r := &http.Request{Header: http.Header{}} r.Header.Set("Authorization", fmt.Sprintf("Bearer %s", tokenStr)) parser := token.NewTokenParser() tok, err := parser.ParseToken(r, b.config.AccessSecret, "") if err != nil { return 0, 0, err } if !tok.Valid { return 0, 0, errors.New("token is invalid") } var userId int var expiredAt int64 if claims, ok := tok.Claims.(jwt.MapClaims); ok { if data, ok := claims["data"]; ok { userId, _ = cast.ToStringMapInt(data)["id"] } if exp, ok := claims["exp"]; ok { expiredAt = cast.ToInt64(exp) } } return userId, expiredAt, nil } // ParseUid 解析出uid func (b *TokenBuilder) ParseUid(r *http.Request) (int, error) { parser := token.NewTokenParser() tok, err := parser.ParseToken(r, b.config.AccessSecret, "") if err != nil { return 0, err } if !tok.Valid { return 0, errors.New("token is invalid") } if claims, ok := tok.Claims.(jwt.MapClaims); ok { if data, ok := claims["data"]; ok { uid, _ := cast.ToStringMapInt(data)["id"] return uid, nil } } return 0, errors.New("token not exist uid") } func ParseUid(r *http.Request, accessSecret string) (int, error) { parser := token.NewTokenParser() tok, err := parser.ParseToken(r, accessSecret, "") if err != nil { return 0, err } if !tok.Valid { return 0, errors.New("token is invalid") } if claims, ok := tok.Claims.(jwt.MapClaims); ok { if data, ok := claims["data"]; ok { uid, _ := cast.ToStringMapInt(data)["id"] return uid, nil } } return 0, errors.New("token not exist uid") }