在 SvelteKit 端点验证 Stripe webhook:如何获取 RequestEvent 的原始主体?

Verifying Stripe webhook in SvelteKit endpoint: how to get the raw body of a RequestEvent?

类似于this question,使用更新版本的 SvelteKit。

上下文:SvelteKit PR #3384 开始将标准 Request 对象传递到端点并删除 rawBody.

上面链接的问题很好地回答了如何使用 rawBody 调用 Stripe 的 constructEvent 来验证传入的 webhook 请求的签名,但现在未修改的主体不再暴露(据我所知),我想知道如何更新我的 webhook 处理程序。

我试过用 request.text()request.json()request.arrayBuffer()(转换为字符串)、request.blob().text()request.blob().text() 的结果调用 constructEvent普通的 request.body 转换为字符串,但其中 none 有效。它总是抛出相同的错误:

No signatures found matching the expected signature for payload.
Are you passing the raw request body you received from Stripe?
https://github.com/stripe/stripe-node#webhook-signing

所以我查看了 node-fetch 源代码,因为那是 svelte-kit 用来填充开发服务器和所有不支持 Fetch 的环境,并且有标准 Request class 没有的方法,那就是 Request.buffer()。通过这种方法,我能够解决该问题。这仅适用于不支持本地提取的节点或无服务器环境(几乎所有环境,除了 cloudflare)。

export async function post({ request }: RequestEvent) {
    try {
        const body = await request.buffer();
        const sig = request.headers.get('stripe-signature') as string;
        const e = stripe.webhooks.constructEvent(body, sig, secret);
        console.log(e.type);
    } catch (_e) {
        console.error(_e);
    }
}

结果:

charge.succeeded
payment_intent.succeeded
payment_intent.created