package jwtx import ( "allapp/conf" "sync" "time" "github.com/golang-jwt/jwt/v4" ) type CustomClaims struct { UserID int64 `json:"user_id"` jwt.RegisteredClaims } type jwtManager struct { secret string tokenExpiry time.Duration } var ( manager *jwtManager once sync.Once ) // InitJwt 初始化全局 JWT 配置 func InitJwt() { once.Do(func() { manager = &jwtManager{ secret: conf.GetConf().JWT.Secret, tokenExpiry: conf.GetConf().JWT.AccessExpiry, // 直接当唯一 token } }) } // CreateToken 创建 JWT func CreateToken(userID int64) (string, error) { if manager == nil { return "", jwt.ErrTokenInvalidClaims } return manager.createToken(userID) } // VerifyToken 校验 JWT(合法 or 不合法) func VerifyToken(tokenString string) (*CustomClaims, bool) { if tokenString == "" || manager == nil { return nil, false } token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) { return []byte(manager.secret), nil }) if err != nil || !token.Valid { return nil, false } claims, ok := token.Claims.(*CustomClaims) if !ok { return nil, false } return claims, true } func (j *jwtManager) createToken(userID int64) (string, error) { now := time.Now() claims := &CustomClaims{ UserID: userID, RegisteredClaims: jwt.RegisteredClaims{ IssuedAt: jwt.NewNumericDate(now), }, } // 只有大于 0 才设置过期时间 if j.tokenExpiry > 0 { claims.ExpiresAt = jwt.NewNumericDate(now.Add(j.tokenExpiry)) } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString([]byte(j.secret)) }