本指南介绍了如何从你的 Cloudflare 运营部署获取令牌。到此阶段,你和 Cloudflare 已经共同构建并部署了以下组件。使用本指南来确认部署能够端对端地颁发和兑换令牌。
Privacy Pass 目前不是自助服务产品:生产部署是与 Cloudflare 合作的托管项目。如果你只是想在不做任何设置的情况下体验 Privacy Pass 的运作,请参阅快速入门。
联系我们 ↗申请访问权限并获取你的颁发者配置。
Cloudflare 部署的内容:
- 一个颁发者端点(在此称为
https://your-issuer.example.com),运行公开的、符合 RFC 9578 规范的颁发者。 - 位于
/.well-known/private-token-issuer-directory的公开目录端点。 - 一个
/token-request端点。
你需要运营或准备好的内容:
- 一个可运行的 Attester,即验证你的声明的服务,一旦客户端通过验证,将盲化令牌请求代理到颁发者。在 Cloudflare 颁发者部署中,客户端从不直接联系颁发者。通常,你需要运营 Attester 以保持角色分离,但 Cloudflare 可以协助构建。有关 Cloudflare Workers 的实现,请参阅 cloudflare/privacypass-attester ↗。
- 源(客户端试图访问的 Web 服务、应用程序或网站),配置为对照颁发者的公钥验证令牌(或在边缘由 Cloudflare 兑换)。
- 你的 Attester 用于向颁发者进行身份验证的 mTLS 客户端证书。
- 用于运行颁发协议的客户端库。库选项包括 TypeScript、Go 和 Rust。
使用适合你技术栈的 Privacy Pass 库实现客户端:
- TypeScript — @cloudflare/privacypass-ts ↗
- Go — cloudflare/pat-go ↗(参考实现,适用于实验和互操作性使用)
- Rust — raphaelrobert/privacypass ↗(未经独立审计)
每个颁发者都在标准目录端点发布其配置。该端点是公开的,因此你可以获取它以确认颁发者可访问并读取其公钥:
curl https://your-issuer.example.com/.well-known/private-token-issuer-directory响应列出了令牌请求端点和颁发者的公钥。令牌类型 2 是 Blind RSA:
{
"issuer-request-uri": "/token-request",
"token-keys": [
{
"token-type": 2,
"token-key": "<base64url 编码的公钥>",
"not-before": 1700000000
}
]
}这些是你的源将用于验证已兑换令牌的密钥。
在此部署中,客户端从不直接联系颁发者。获取令牌需要跨所有四个角色进行往返:
- 源返回
WWW-Authenticate挑战。 - 客户端与你的 Attester 完成验证,并向其发送盲化令牌请求。
- Attester 验证客户端,然后对颁发者进行身份验证(例如通过 mTLS)并将请求代理到颁发者的
/token-request端点。 - 颁发者对盲化请求进行签名并返回;客户端对其进行去盲化以恢复最终令牌,然后在源处兑换它。
Origin Client Attester Issuer
│ │ │ │
│- TokenChallenge ─>│ │ │
│ │<== Attestation ==>│ │
│ │ │── TokenRequest ─>│
│ │ │<─ TokenResponse ─│
│ │<── TokenResponse ──│ │
│<─ Request+Token -─│ [finalize token] │ │
│────- 200 OK ────->│ │ │在此示例中使用 TypeScript 库,客户端构建盲化令牌请求,然后将其发送给你的 Attester,Attester 将其代理到颁发者并返回签名响应:
import { publicVerif } from '@cloudflare/privacypass-ts';
const { BlindRSAMode, Client } = publicVerif;
// 声明你自己的 sendToAttester 传输函数——见下方说明。
declare function sendToAttester(tokenRequest: Uint8Array): Promise<Uint8Array>;
// `tokenChallenge` 来自源的 WWW-Authenticate 标头。
// `issuerPublicKey` 是颁发者的公钥字节(来自步骤 1 中的目录)。
const client = new Client(BlindRSAMode.PSS);
const tokenRequest = await client.createTokenRequest(tokenChallenge, issuerPublicKey);
// 将盲化请求发送给你的 Attester。它验证客户端,将请求代理到
// 颁发者,并返回颁发者签名的令牌响应。
const tokenResponseBytes = await sendToAttester(tokenRequest.serialize());
// 反序列化并去盲化以恢复最终令牌。
const tokenResponse = client.deserializeTokenResponse(tokenResponseBytes);
const token = await client.finalize(tokenResponse);然后客户端通过在 Authorization 标头中将令牌发送到源来兑换该令牌。源(或在边缘由 Cloudflare——参阅部署模型)对照颁发者的公钥验证签名,并以 200 OK 响应。
两个信号确认颁发和兑换端对端正常工作:
- 目录端点返回颁发者的
token-keys。 - 已兑换的令牌对照颁发者的公钥验证通过,源返回
200 OK。
要检查目录端点是否可访问,可以使用 Privacy Pass 演示工具 ↗来获取颁发者的目录。
- Privacy Pass 协议 — 四个角色、颁发和兑换流程以及生成令牌的盲签名。
- 部署模型 — 各角色的运营者和部署模型。
- cloudflare/privacypass-attester ↗ — 参考验证者实现(Turnstile 验证,将令牌请求代理到颁发者)。
- cloudflare/privacypass-issuer ↗ — 参考颁发者实现(Workers,密钥轮换)。