一、令牌家族与撤销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 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部