Files

46 lines
1.3 KiB
Go

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
}