4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[TypeScript] LINE Messaging APIを使うときは署名を検証しよう

Last updated at Posted at 2024-07-08

LINE Messaging APIの署名の検証とは

LINE Messaging APIについて、公式サイトには以下のような記述があります。

署名を検証する

リクエストがLINEプラットフォームから送られたことを確認するために、ボットサーバーでリクエストヘッダーのx-line-signatureに含まれる署名を検証します。

検証の手順は以下のとおりです。

  1. リクエストボディのダイジェストを計算します。チャネルシークレットを秘密鍵としてHMAC-SHA256アルゴリズムを使用します。
  2. ダイジェストをBase64エンコードし、リクエストヘッダーのx-line-signatureに含まれる署名と一致するかどうかを確認します。

https://developers.line.biz/ja/reference/messaging-api/#signature-validation

上記のように、webhookのPOSTリクエストが本当にLINEから送られてきたものかを確かめる必要があります。これが署名の検証と呼ばれる処理です。

TypeScript(JavaScript)を用いて署名の検証を行う方法には、以下の2つがあります。

署名の検証方法1: expressミドルウェアを使う

LINEは公式のTypeScript SDKを提供しています。
この公式SDKの中に、expressミドルウェアとして使うことができる関数があります。

// https://line.github.io/line-bot-sdk-nodejs/guide/webhook.html
import express from 'express'
import { middleware } from '@line/bot-sdk'

const app = express()

const config = {
  channelSecret: 'YOUR_CHANNEL_SECRET'
}

app.post('/webhook', middleware(config), (req, res) => {
  req.body.events // webhook event objects from LINE Platform
  req.body.destination // user ID of the bot
  ...
})

app.listen(8080)

方法2: express以外で署名の検証をする

expressを使っている場合は方法1のミドルウェアでよいのですが、express以外のライブラリを使ってサーバーを立てている場合は、同じく公式SDKの中にあるvalidateSignature関数を使います。

import {
  messagingApi,
  SignatureValidationFailed,
  validateSignature,
  type WebhookRequestBody,
} from "npm:@line/bot-sdk@9.2.2";

// チャネル基本設定の「チャネルシークレット」の値
const CHANNEL_SECRET = process.env.CHANNEL_SECRET;

app.post("/webhook", req => {

  // POSTのrequest bodyを文字列で取得
  const body = await await req.text();
  // x-line-signatureヘッダーを取得
  const signature = req.header("x-line-signature")!;
  // 署名を検証し、LINEから送られたものではないと判断したらエラーを投げる
  if (!validateSignature(body, CHANNEL_SECRET, signature)) {
    throw new SignatureValidationFailed("signature validation failed", {
      signature,
    });
  }

  // 以下、返信処理など
  const data = JSON.parse(body);
  ...
});

まずvalidateSignature関数を呼びだし、署名の検証を行います。
引数は

  • body(リクエスト本文)
  • CHANNEL_SECRET(LINEから提供されるチャネルシークレット)
  • signaturex-line-signatureヘッダーの値)

です。
この関数は署名の検証に成功した場合trueを、失敗した場合falseを返します。

署名の検証に失敗した場合はエラーにします。LINEのSDKは、署名に失敗した場合のエラーを表すSignatureValidationFailedエラーを提供しているので、これをthrowしてあげるようにします。

まとめ

LINE Messaging APIを使うときは、webhookが本当にLINEから送信されたものかを検証するために、署名の検証が必要です。
公式のSDKを使うと実装が楽になるのでおすすめです!

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
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?