こんにちは。
株式会社dottでエンジニャーをしているHALです。
弊社ではHeadless CMSのStrapiを活用したWEBシステムの開発をやっていたりします。
Strapiは、通常POSTリクエストなどを受け付けると、bodyを勝手にパースしてオブジェクトにしてくれます。
基本的には便利なので良いのですが、稀にパース前の生のbodyが必要になることがあります。
例えばLINEのMessaging APIのWebhookからリクエストを受け付けた時で、署名の検証のために生のbodyが必要な場合など。
そんな時に必要になる設定を調べました。
middlewares.jsの修正
strapi/config/middlewares.js
の記述を修正します。
module.exports = [
"strapi::errors",
"strapi::security",
"strapi::cors",
"strapi::poweredBy",
"strapi::logger",
"strapi::query",
- "strapi::body",
+ { name: "strapi::body", config: { includeUnparsed: true } },
"strapi::session",
"strapi::favicon",
"strapi::public",
];
これでパース前の生のbodyがctx.request.bodyに含まれるようになります。
ちなみに追加できるオプションの一覧はこちら。
Strapiの内部で使用しているKoaというライブラリに渡している値になります。
生のbodyの使い方
実際に生のbodyを使うときは以下のようにします。
(LINEの署名検証のpolicyの例。参考にしたのはこちら)
module.exports = async (policyContext, config, { strapi }) => {
const crypto = require("crypto");
const channelSecret = CHANNEL_SECRET; // Channel secret string
const unparsed = require("koa-body/unparsed.js");
const body = policyContext.request.body[unparsed];
if (!body) {
return true;
}
const signature = crypto
.createHmac("SHA256", channelSecret)
.update(body)
.digest("base64");
// Compare x-line-signature request header and the signature
if (policyContext.request.header["x-line-signature"] === signature) {
return true;
}
return false;
};
重要なのは以下の2行です。
const unparsed = require("koa-body/unparsed.js");
const body = policyContext.request.body[unparsed];
koa-body/unparsed.js
というやつを使うことで取得できるようです。
署名の検証に生のbodyが必要になる例は他のサービスのwebhookなどでもよくあるパターンなので、同様にすれば利用できると思います。
最後に
StrapiはヘッドレスCMSとしても優秀ですし、カスタマイズすればWEB開発にも活かせます。
ただ、最近v3からv4に変わった際に大幅に中身が変わっていて、検索してもv3の情報ばかりでv4の情報がなかったりして困ります・・・。
(公式ドキュメントもカスタマイズするのにはちょっと説明が薄く・・・)
またv4でちょっと特殊なことをしようとした際は記事にしてみようと思います。
Strapi、便利なのでぜひ使ってみてください。