package jwt import ( "fmt" "time" "github.com/golang-jwt/jwt/v5" ) // Claims 结构定义 type Claims struct { UserID string `json:"user_id"` Username string `json:"username"` TenantID string `json:"tenant_id"` ProjectID string `json:"project_id"` Extra map[string]interface{} `json:"extra,omitempty"` jwt.RegisteredClaims } // CreateToken 创建Token // claims: Claims对象 // expiresHours: 过期小时数(0表示默认7天) // secretKey: 密钥 func CreateToken(claims *Claims, expiresHours int, secretKey string) (string, error) { return createTokenInternal(claims, 0, expiresHours, secretKey) } // CreateTokenDays 创建Token(按天) // claims: Claims对象 // expiresDays: 过期天数(优先使用) // secretKey: 密钥 func CreateTokenDays(claims *Claims, expiresDays int, secretKey string) (string, error) { return createTokenInternal(claims, expiresDays, 0, secretKey) } // 内部实现 func createTokenInternal(claims *Claims, expiresDays, expiresHours int, secretKey string) (string, error) { if secretKey == "" { return "", fmt.Errorf("secret key is required") } if claims == nil { return "", fmt.Errorf("claims cannot be nil") } // 计算过期时间 var expiresDuration time.Duration if expiresDays > 0 { expiresDuration = time.Duration(expiresDays) * 24 * time.Hour } else if expiresHours > 0 { expiresDuration = time.Duration(expiresHours) * time.Hour } else { // 默认7天 expiresDuration = 7 * 24 * time.Hour } // 设置时间字段(内部处理) now := time.Now() claims.RegisteredClaims = jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(now.Add(expiresDuration)), IssuedAt: jwt.NewNumericDate(now), NotBefore: jwt.NewNumericDate(now), Issuer: "jwt-app", Subject: claims.UserID, } // 生成Token token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString([]byte(secretKey)) } // ParseToken 解析Token // tokenString: Token字符串 // secretKey: 密钥 func ParseToken(tokenString, secretKey string) (*Claims, error) { if secretKey == "" { return nil, fmt.Errorf("secret key is required") } claims := &Claims{} token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) { return []byte(secretKey), nil }) if err != nil { return nil, fmt.Errorf("parse token failed: %w", err) } if !token.Valid { return nil, fmt.Errorf("invalid token") } return claims, nil } // ValidateToken 验证Token是否有效 func ValidateToken(tokenString, secretKey string) bool { _, err := ParseToken(tokenString, secretKey) return err == nil } // RefreshToken 刷新Token func RefreshToken(tokenString string, expiresHours int, secretKey string) (string, error) { // 解析原Token claims, err := ParseToken(tokenString, secretKey) if err != nil { return "", err } // 重新创建Token return CreateToken(claims, expiresHours, secretKey) }