Webhookのテストにはngrok
背景
LINE CHAT BOT を開発していると、実装が正しく動いているかどうかをテストしたいが、その都度 Heroku へデプロイするのも面倒だなぁという場面に何度も遭遇する。
Webアプリの挙動確認であれば、ローカルサーバを立てることで簡単にテストできるのだろうが、LINE BOT だとそうはいかない。なぜなら、LINE Messageing API は 外部(LINEプラットフォーム) から ボットサーバのWebhook URL へとイベントが送信され、それに応じてユーザにレスポンスを返すという形式だからだ。
例えば、今回利用したフレームワーク Flask では、hostを0.0.0.0
に設定してローカルサーバを起動してやれば、外部のネットワークからのアクセスを許可することができる。
Externally Visible Server
If you run the server you will notice that the server is only accessible from your own computer, not from any other in the network. This is the default because in debugging mode a user of the application can execute arbitrary Python code on your computer.
If you have the debugger disabled or trust the users on your network, you can make the server publicly available simply by adding --host=0.0.0.0 to the command line:
$ flask run --host=0.0.0.0
This tells your operating system to listen on all public IPs.
しかし、もう一つ問題がある。それは、Webhook URL には、HTTPS で通信可能なエンドポイントを設定しないといけないこと。
ngrokはこれらの問題を解決してくれる。
ngrokとは
ngrok(エングロック)はローカルサーバを外部ネットワークに簡単に公開できるトンネリングツールである。http://{ランダムな文字列}.ngrok.io
のような公開URLを設定し、そのURLへのをリクエストをlocalhostにフォワーディングしてくれる。httpsによる通信が可能な公開URLも作成できる。
ngrokの導入/使い方
macOSであれば Homebrew を使って、ngrok を簡単にインストールできる。
$ brew install ngrok
利用するときは、まずローカルサーバを立ち上げ、同一のポート番号で
$ ngrok http [ポート番号]
とやってやるだけ。
すると、
ngrok (Ctrl+C to quit)
Visit http://localhost:4040/ to inspect, replay, and modify your requests
Session Status online
Session Expires 1 hour, 51 minutes
Terms of Service https://ngrok.com/tos
Version 3.0.6
Region Japan (jp)
Latency 23ms
Web Interface http://127.0.0.1:4040
Forwarding https://f02c-92-202-33-104.jp.ngrok.io -> http://localhost:5002
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
となって、Forwarding に公開URLが表示される。(今回であれば、https://f02c-92-202-33-104.jp.ngrok.io -> http://localhost:5002
)
ngrokの注意点
-
サブドメインの固定化
ngrokが公開するURLのサブドメインは- ランダムな文字列
- 立ち上げるたびに変わる
という特徴があるが、ngrokにサインアップして、authtokenを発行することでサブドメインの固定化ができるらしい。有料プランに加入しないといけないかも??
-
セキュリティリスク
URLを異なるネットワークから誰でもアクセスできるような形で公開している以上、セキュリティ面を考える必要が出てくる。→ Basic認証の導入ngrokでは、上の 1.サブドメインの固定化 でも触れた authtoken を発行して、
Terminalngrok http -auth="username:password" [ポート番号]
で起動することで、
username
とpassword
を利用したBasic認証を設定することができる。
Discussion