package middleware import ( "context" "time" "github.com/golang-jwt/jwt/v5" ) // RevokeToken 将令牌加入黑名单(按 jti,若无 jti 则按 subject+签发时间) func RevokeToken(claims *JWTClaims, tokenStr string, exp time.Time) error { if authState == nil { return stateUnavailable("吊销令牌") } return authState.RevokeToken(context.Background(), tokenIdentifier(claims), exp) } // IsRevoked 判断令牌是否已被吊销 func IsRevoked(claims *JWTClaims) (bool, error) { if authState == nil { return false, stateUnavailable("校验令牌吊销状态") } return authState.IsTokenRevoked(context.Background(), tokenIdentifier(claims)) } // ExtractClaims 从 token 字符串解析 claims(供 logout handler 使用) func ExtractClaims(tokenStr string, secret string) (*JWTClaims, *jwt.Token, error) { claims := &JWTClaims{} token, err := jwt.ParseWithClaims(tokenStr, claims, func(t *jwt.Token) (interface{}, error) { return []byte(secret), nil }, jwt.WithValidMethods([]string{"HS256"})) return claims, token, err } // tokenIdentifier 返回令牌唯一标识:优先 jti,否则用 subject+签发时间 func tokenIdentifier(claims *JWTClaims) string { if claims.ID != "" { return claims.ID } iat := "" if claims.IssuedAt != nil { iat = claims.IssuedAt.Format(time.RFC3339Nano) } return claims.Subject + "|" + iat }