一、令牌家族与撤销type Rt = { jti: string; family: string; userId: string; exp: number; revoked?: boolean } class RtStore { byJti = new Map<string, Rt>(); byFamily = new Map<string, Set<string>>(); add(rt: Rt) { this.byJti.set(rt.jti, rt); const s = this.byFamily.get(rt.family) || new Set<string>(); s.add(rt.jti); this.byFamily.set(rt.family, s) } revokeJti(jti: string) { const r = this.byJti.get(jti); if (r) r.revoked = true } revokeFamily(f: string) { for (const j of this.byFamily.get(f) || []) this.revokeJti(j) } } 二、登出事件与广播type LogoutEvent = { userId: string; family?: string; timestamp: string } type Bus = { publish: (evt: LogoutEvent) => void; subscribe: (fn: (evt: LogoutEvent) => void) => void } 三、后通道登出(Back-Channel)type Req = { body: { userId: string; family?: string } } type Res = { status: (n: number) => Res; end: (b?: string) => void } function backChannelLogout(req: Req, res: Res, store: RtStore, bus: Bus) { const userId = req.body.userId const family = req.body.family if (family) store.revokeFamily(family) const evt = { userId, family, timestamp: new Date().toISOString() } bus.publish(evt) res.end(JSON.stringify({ ok: true })) } 四、前通道登出(Front-Channel)function frontChannelLogout(res: Res) { res.end('<iframe src="/logout" hidden></iframe>') } 五、网关黑名单校验type GateReq = { headers: Record<string, string | undefined> } type GateRes = { status: (n: number) => GateRes; end: (b?: string) => void } function gatewayCheck(req: GateReq, res: GateRes, store: RtStore) { const token = req.headers['authorization'] || '' const jti = token.split('.').pop() || '' const rt = store.byJti.get(jti) if (rt?.revoked) return res.status(401).end('revoked') } 六、Webhook通知(可选)type WebReq = { url: string; body: string } async function notifyWebhook(req: WebReq) { /* 实际实现由平台提供 */ } 七、验收清单后通道登出撤销令牌家族并广播事件;前通道兼容跨站登出。网关校验令牌`jti`黑名单,撤销后拒绝;Webhook通知上下游服务。审计包含`userId/family/jti/timestamp`;TTL策略清理过期令牌与家族。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部
1.917814s