LoginSignup
5
3

More than 3 years have passed since last update.

【NestJS】stripe webhookの署名検証

Last updated at Posted at 2021-03-03

概要

  1. 署名シークレットを取得
  2. リクエストに rawBody を追加する
  3. コントローラで request.rawBody より rawBody を取得する
  4. コントローラで stripe-signature より ヘッダの署名を取得する
  5. 署名の検証

ハマりポイント

署名の検証時に raw body が必要になるため、リクエストに rawBody を追加する必要がある

1. 署名シークレットを取得

  • 開発者の Webhook をクリック

image.png

  • エンドポイントを追加後、署名シークレットを取得

    • prefixwhsec_

image.png

2. リクエストに raw body を追加する

  • before

nest new [name] で生成した結果

main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
  • after

リクエストに raw body を追加する

main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { json } from 'body-parser';

const cloneBuffer = require('clone-buffer');

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(
    json({
      verify: (req, res, buf, encoding) => {
        // リクエストに `raw body` を追加する
        if (req.headers['stripe-signature'] && Buffer.isBuffer(buf)) {
          (req as any).rawBody = cloneBuffer(buf);
        }
        return true;
      },
    }),
  );

  await app.listen(3000);
}
bootstrap();

3. コントローラから request.rawBodyrawBody を取得する

  • @Req を利用し、request を取得
controller.ts
@Req() request: Request
  • request から rawBody を取得する
controller.ts
(request as any).rawBody

4. コントローラで stripe-signature より ヘッダの署名を取得する

  • @Headers を利用し、stripe-signature ヘッダの値を取得
controller.ts
@Headers('stripe-signature') sig,

5. 署名の検証

stripe = new Stripe()
stripe.webhooks.constructEvent(
  (request as any).rawBody,
  sig,
  'whsec_...'
)

参考文献

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3