package jwt import ( "time" "github.com/golang-jwt/jwt/v5" ) // JWTManager JWT管理器接口 type JWTManager interface { GenerateToken(claims map[string]interface{}, expiration time.Duration) (string, error) ValidateToken(tokenString string) (map[string]interface{}, error) RefreshToken(tokenString string, expiration time.Duration) (string, error) } // jwtManager JWT管理器实现 type jwtManager struct { secretKey []byte issuer string } // NewJWTManager 创建新的JWT管理器 func NewJWTManager(secretKey string, issuer string) JWTManager { return &jwtManager{ secretKey: []byte(secretKey), issuer: issuer, } } // GenerateToken 生成JWT令牌 func (j *jwtManager) GenerateToken(claims map[string]interface{}, expiration time.Duration) (string, error) { // 创建标准声明 standardClaims := jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(time.Now().Add(expiration)), IssuedAt: jwt.NewNumericDate(time.Now()), Issuer: j.issuer, } // 合并自定义声明和标准声明 allClaims := make(map[string]interface{}) for k, v := range claims { allClaims[k] = v } allClaims["exp"] = standardClaims.ExpiresAt allClaims["iat"] = standardClaims.IssuedAt allClaims["iss"] = standardClaims.Issuer // 创建令牌 token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims(allClaims)) // 签名令牌 return token.SignedString(j.secretKey) } // ValidateToken 验证JWT令牌 func (j *jwtManager) ValidateToken(tokenString string) (map[string]interface{}, error) { token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { // 验证签名方法 if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, jwt.ErrSignatureInvalid } return j.secretKey, nil }) if err != nil { return nil, err } if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { return claims, nil } return nil, jwt.ErrInvalidKey } // RefreshToken 刷新JWT令牌 func (j *jwtManager) RefreshToken(tokenString string, expiration time.Duration) (string, error) { // 验证原令牌 claims, err := j.ValidateToken(tokenString) if err != nil { return "", err } // 移除时间相关声明 delete(claims, "exp") delete(claims, "iat") delete(claims, "nbf") // 生成新令牌 return j.GenerateToken(claims, expiration) }