feat: 建立可靠通知、吊销与跨实例状态
This commit is contained in:
@@ -1,45 +1,26 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
)
|
||||
|
||||
// tokenBlacklist 登出令牌黑名单(内存版,进程重启后失效,令牌自然过期兜底)
|
||||
type tokenBlacklist struct {
|
||||
mu sync.RWMutex
|
||||
revoked map[string]time.Time // tokenID(jti) -> 过期时间
|
||||
}
|
||||
|
||||
var defaultBlacklist = &tokenBlacklist{revoked: make(map[string]time.Time)}
|
||||
|
||||
// RevokeToken 将令牌加入黑名单(按 jti,若无 jti 则按 subject+签发时间)
|
||||
func RevokeToken(claims *JWTClaims, tokenStr string, exp time.Time) {
|
||||
id := tokenIdentifier(claims)
|
||||
defaultBlacklist.mu.Lock()
|
||||
defaultBlacklist.revoked[id] = exp
|
||||
defaultBlacklist.mu.Unlock()
|
||||
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 {
|
||||
id := tokenIdentifier(claims)
|
||||
defaultBlacklist.mu.RLock()
|
||||
exp, ok := defaultBlacklist.revoked[id]
|
||||
defaultBlacklist.mu.RUnlock()
|
||||
if !ok {
|
||||
return false
|
||||
func IsRevoked(claims *JWTClaims) (bool, error) {
|
||||
if authState == nil {
|
||||
return false, stateUnavailable("校验令牌吊销状态")
|
||||
}
|
||||
// 已过期的黑名单项自动清理
|
||||
if time.Now().After(exp) {
|
||||
defaultBlacklist.mu.Lock()
|
||||
delete(defaultBlacklist.revoked, id)
|
||||
defaultBlacklist.mu.Unlock()
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return authState.IsTokenRevoked(context.Background(), tokenIdentifier(claims))
|
||||
}
|
||||
|
||||
// ExtractClaims 从 token 字符串解析 claims(供 logout handler 使用)
|
||||
|
||||
Reference in New Issue
Block a user