Files
Edu/services/iam/src/shared/cache/token-blacklist.service.ts
SpecialX a35e759d64 feat(iam): 完整实现 iam 身份认证与权限服务
包含 jwt/jwks/audit/grpc、rbac、cache、redis/kafka 配置等完整实现
2026-07-10 19:09:39 +08:00

39 lines
1.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Injectable } from "@nestjs/common";
import { getRedis } from "../../config/redis.js";
/**
* Token 黑名单服务I7 裁决JWT 黑名单)。
*
* 用于 logout / refresh 轮换场景,将未过期的 refresh_token 的 jti 加入黑名单,
* 阻止其再次被用于刷新 access_token。
*
* 缓存策略:
* - Key: `iam:bl:{jti}` → "1"
* - TTL: 与 refresh_token 剩余有效期对齐(避免永久驻留)
*
* access_token 不走黑名单(短生命周期 15min自然过期
*/
@Injectable()
export class TokenBlacklistService {
private static buildKey(jti: string): string {
return `iam:bl:${jti}`;
}
async isBlacklisted(jti: string): Promise<boolean> {
const redis = getRedis();
const exists = await redis.exists(TokenBlacklistService.buildKey(jti));
return exists === 1;
}
/**
* 将 jti 加入黑名单。
* @param jti JWT ID
* @param ttlSeconds 剩余有效期(秒),到期后自动清理
*/
async blacklist(jti: string, ttlSeconds: number): Promise<void> {
if (ttlSeconds <= 0) return; // 已过期,无需加入
const redis = getRedis();
await redis.set(TokenBlacklistService.buildKey(jti), "1", "EX", ttlSeconds);
}
}