2

我的 SvelteKit 应用程序中有一个端点,用于处理来自 Stripe 的 webhook 请求。每个请求都经过签名,以便可以验证它来自 Stripe。

我必须验证事件是否来自 Stripe 的代码如下所示:

import Stripe from "stripe";

const WEBHOOK_SECRET = process.env["STRIPE_WH_SECRET"];

const stripe = new Stripe(process.env["STRIPE_SECRET"], {
  apiVersion: "2020-08-27",
});

export async function post({ headers, body }) {
  let event: Stripe.Event;
  try {
    event = stripe.webhooks.constructEvent(
      body,
      headers["stripe-signature"],
      WEBHOOK_SECRET
    );
  } catch (err) {
    return {
      status: 400,
      body: err,
    };
  }

  // Do stuff with the event
}

但是当它从 Stripe 接收到一个事件时,我得到了这个错误:

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

经过一番研究,我发现这个函数在调用SvelteKit 钩子之前将 body 解析为 JSON,这意味着无法直接获取原始 body,所以我决定最好的选择是尝试重建原始 body:

event = stripe.webhooks.constructEvent(
  JSON.stringify(body),
  headers["stripe-signature"],
  WH_SECRET
);

我不完全确定为什么这不起作用,因为在挖掘了 Stripe 库中的相关代码之后,它似乎可以很好地处理字符串。我最好的猜测是,在某些时候编码会变得混乱。

对此的任何帮助将不胜感激,因为我真的很想避免离开 SvelteKit,因为我实际上已经完成了我的项目(回想起来,这不是一个好主意)。

4

1 回答 1

1

接受的负载stripe.webhooks.constructEvent(payload, signature, secret)必须是 type string | Buffer,但在 SvelteKit 请求中收到的 rawBody 是 type Uint8Array

传递 Uint8Array rawBody 或 JSON.stringify'd rawBody 作为有效负载会导致 Stripe 出现以下错误。参考:https ://github.com/stripe/stripe-node#webhook-signing

错误 message: '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'

我们需要将 rawBody 转换为 astringBuffer不改变内容。为此,我们可以使用:Buffer.from(rawBody).

所以你的端点看起来像:

...
const stripeWebhookSecret = process.env['STRIPE_WEBHOOK_SECRET'];

export const post: RequestHandler = async (request) => {
  const rawBody = Buffer.from(request.rawBody);
  const signature = request.headers['stripe-signature'];

  try {
    event = stripe.webhooks.constructEvent(
      rawBody,
      signature,
      stripeWebhookSecret
    );
...
于 2021-09-22T03:07:24.443 回答