package token import ( "encoding/base64" "encoding/json" "strings" "time" "git.apinb.com/bsm-sdk/core/errcode" "git.apinb.com/bsm-sdk/core/vars" "github.com/golang-jwt/jwt/v5" ) type Claims struct { ID uint `json:"id"` Identity string `json:"identity"` Extend map[string]string `json:"extend"` Client string `json:"client"` Owner any `json:"owner"` Role string `json:"role"` jwt.RegisteredClaims // v5版本新加的方法 } type tokenJwt struct { SecretKey string } func New(secretKey string) *tokenJwt { return &tokenJwt{SecretKey: secretKey} } // 生成JWT func (t *tokenJwt) GenerateJwt(id uint, identity, client, role string, owner any, extend map[string]string) (string, error) { keyLen := len(t.SecretKey) if !(keyLen == 16 || keyLen == 24 || keyLen == 32) { return "", errcode.ErrTokenSecretKey } now := time.Now() claims := Claims{ ID: id, Identity: identity, Client: client, Extend: extend, Owner: owner, Role: role, RegisteredClaims: jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(now.Add(vars.JwtExpire)), // 过期时间24小时 IssuedAt: jwt.NewNumericDate(now), // 签发时间 NotBefore: jwt.NewNumericDate(now), // 生效时间 }, } // 使用HS256签名算法 token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) s, err := token.SignedString([]byte(t.SecretKey)) if err != nil { return "", errcode.String(errcode.ErrTokenGenerate, err.Error()) } return s, nil } // 解析JWT func (t *tokenJwt) ParseJwt(tokenstring string) (*Claims, error) { token, err := jwt.ParseWithClaims(tokenstring, &Claims{}, func(token *jwt.Token) (interface{}, error) { return []byte(t.SecretKey), nil }) if claims, ok := token.Claims.(*Claims); ok && token.Valid { return claims, nil } else { return nil, errcode.String(errcode.ErrTokenParse, err.Error()) } } // 验证JWT是否过期 func (t *tokenJwt) IsExpired(tokenstring string) (bool, error) { // 分割JWT的三个部分 parts := strings.Split(tokenstring, ".") if len(parts) != 3 { return true, errcode.ErrTokenDataInvalid } // 解码Payload部分 payload, err := base64.RawURLEncoding.DecodeString(parts[1]) if err != nil { return true, errcode.String(errcode.ErrTokenBase64Decode, err.Error()) } // 解析JSON var claims jwt.RegisteredClaims if err := json.Unmarshal(payload, &claims); err != nil { return true, errcode.String(errcode.ErrTokenJsonDecode, err.Error()) } // 检查过期时间 currentTime := time.Now().Unix() return claims.ExpiresAt.Unix() < currentTime, nil }