示例代码
// 1. 登录成功后启动 DBSC 注册
app.post("/login", async (req, res) => {
const session = await createPendingDbscSession(req.user.id);
res.setHeader("Secure-Session-Registration", `(ES256 RS256); path="/StartSession"; challenge="${session.challenge}"`);
res.setHeader("Sec-Session-Registration", `(ES256 RS256); path="/StartSession"; challenge="${session.challenge}"`);
res.setHeader("Set-Cookie", `__Host-dbsc_boot=${session.id}; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=300`);
res.status(200).json({ ok: true });
});
// 2. Chrome 回调 /StartSession,服务端验证 Secure-Session-Response 后签发短 Cookie
app.post("/StartSession", async (req, res) => {
const bootSessionId = readCookie(req, "__Host-dbsc_boot");
const proof = readStructuredHeaderString(req.header("Secure-Session-Response"));
const session = await findPendingDbscSession(bootSessionId);
const verified = await verifyRegistrationProof(proof, session.registrationChallenge);
await bindPublicKeyToSession(session.id, verified.publicKey);
const shortGrant = await rotateShortGrant(session.id);
res.setHeader("Set-Cookie", `__Host-dbsc_auth=${shortGrant}; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=90`);
res.json({
session_identifier: session.id,
refresh_url: "/RefreshEndpoint",
scope: { origin: "https://dbsc.chromesec.org", include_site: false },
credentials: [{ type: "cookie", name: "__Host-dbsc_auth", attributes: "Path=/; Secure; HttpOnly; SameSite=Lax" }],
});
});
// 3. 短 Cookie 过期时,/RefreshEndpoint 发挑战并验证 Chrome 的刷新证明
app.post("/RefreshEndpoint", async (req, res) => {
const sessionId = readStructuredHeaderString(req.header("Sec-Secure-Session-Id"));
const proof = readStructuredHeaderString(req.header("Secure-Session-Response"));
if (!proof) {
const challenge = await createSingleUseRefreshChallenge(sessionId);
res.setHeader("Secure-Session-Challenge", `"${challenge}"; id="${sessionId}"`);
return res.status(403).json({ error: "challenge_required" });
}
const session = await verifyRefreshProofAndRotateGrant(proof);
res.setHeader("Set-Cookie", `__Host-dbsc_auth=${session.shortGrant}; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=90`);
res.json({ ok: true });
});