背景与价值直接在前端存储访问令牌存在风险。BFF通过服务端封装令牌并以HttpOnly Cookie维持会话,降低泄露面。统一规范HttpOnly Cookie:前端仅持有会话标识,不持有访问令牌。令牌封装:网关以后端到后端模式携带令牌调用下游。会话存储:令牌与权限数据存储在服务端,按会话ID映射。核心实现会话与令牌映射type Sess = { id: string; userId: string; createdAt: number }

type TokenInfo = { accessToken: string; exp: number; scope: string }

class Store {

sess = new Map<string, Sess>()

token = new Map<string, TokenInfo>() // key: session id

now(): number { return Date.now() }

create(userId: string): Sess { const s: Sess = { id: Math.random().toString(36).slice(2), userId, createdAt: this.now() }; this.sess.set(s.id, s); return s }

bind(sessId: string, t: TokenInfo) { this.token.set(sessId, t) }

getToken(sessId: string): TokenInfo | undefined { const t = this.token.get(sessId); if (!t) return; if (t.exp * 1000 < this.now()) return; return t }

}

网关封装调用type Req = { cookies: Record<string, string | undefined>; path: string }

type Res = { setHeader: (k: string, v: string) => void; status: (n: number) => Res; end: (b?: string) => void }

function setSessCookie(res: Res, id: string) { res.setHeader('Set-Cookie', `sid=${id}; Path=/; HttpOnly; Secure; SameSite=Lax`) }

async function proxy(req: Req, res: Res, store: Store): Promise<void> {

const sid = req.cookies['sid']

const t = sid ? store.getToken(sid) : undefined

if (!t) { res.status(401).end('unauthorized'); return }

res.setHeader('X-Auth-Forwarded', 'true')

res.end(JSON.stringify({ ok: true, path: req.path, scope: t.scope }))

}

落地建议使用BFF网关以HttpOnly Cookie维持会话,令牌仅存在服务端,避免浏览器泄露。对下游调用统一封装并审计,按会话ID检索令牌与权限细节。验证清单会话Cookie是否为HttpOnly/Secure/SameSite;令牌是否仅在服务端存储与封装调用。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部