package utils import ( "errors" "time" "github.com/golang-jwt/jwt/v5" ) // Claims JWT 声明 // Logan.Li type Claims struct { UserID uint `json:"user_id"` Username string `json:"username"` Role string `json:"role"` jwt.RegisteredClaims } // AccessTokenTTL 访问令牌有效期(配合刷新令牌使用,过期后由前端静默刷新) // Logan.Li const AccessTokenTTL = 24 * time.Hour // AccessTokenTTLSeconds 访问令牌有效期(秒,供响应体 expires_in 使用) // Logan.Li func AccessTokenTTLSeconds() int64 { return int64(AccessTokenTTL / time.Second) } // GenerateToken 生成 JWT 令牌(HS256,24h 过期) // Logan.Li func GenerateToken(userID uint, username, role, secret string) (string, error) { claims := Claims{ UserID: userID, Username: username, Role: role, RegisteredClaims: jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(time.Now().Add(AccessTokenTTL)), IssuedAt: jwt.NewNumericDate(time.Now()), Issuer: "opsx-licence", }, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString([]byte(secret)) } // ParseToken 解析并校验 JWT 令牌 // Logan.Li func ParseToken(tokenString, secret string) (*Claims, error) { token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) { // 确保使用 HMAC 签名方法,防止算法混淆攻击 // Logan.Li if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, errors.New("非预期的签名算法") } return []byte(secret), nil }) if err != nil { return nil, err } if claims, ok := token.Claims.(*Claims); ok && token.Valid { return claims, nil } return nil, errors.New("无效的令牌") }