Posted at

Twilio Functionsを外部からセキュアに呼び出す

More than 1 year has passed since last update.


はじめに

Twilioには、サーバーレスアーキテクチャーである Twilio Functions というサービスがあります。この仕組を使うことで、ユーザ側にサーバーを用意せずに、動的なTwiMLを生成したり、TwilioのRestAPIで電話やSMSを操作することができます。

Functionsを実行するためには、Functionsを作成したときに自動的に生成されるURLを呼び出す必要があります。

この記事では、Functionsの呼び出し時のセキュリティ対策として、「ACCESS CONTROL」を活用する方法を記載します。


ACCESS CONTROLとは

Twilioには、Functionsに限らず、Twilioからの正式なリクエストであることを証明するために、バリデーションリクエストという仕組みが用意されています。具体的には、TwilioからのリクエストURLやパラメータに対して、ユーザしか知り得ないAuth Tokenでハッシュ値を取って、それをX-Twilio-SignatureというHTTPヘッダーオプションの入れています。

ユーザ側は、このヘッダー値を自ら検証することで、本当にTwilioからのリクエストであること、パラメータを含め改ざんがされていないことを保証することができます。

Twilio Functionsには、Functionsの生成時に以下のACCESS CONTROLオプションがあります。

スクリーンショット 2018-04-11 09.32.46.png

このチェックボックスをONにすることで、上記のバリデーションリクエストがFunctions実行時に検証されます。

すなわち、Twilio内部からのアクセスに制限する場合(たとえば、電話番号の着信設定時のURLとしてFunctionsを指定する場合など)は、チェックをONにしておくことが推奨されます。


外部からのFunctions呼び出しでバリデーションリクエストを利用する

上記のように、X-Twilio-Signatureを検証するのが、ACCESS CONTROLの目的ですので、外部のサーバーからFunctionsをコールする場合も、Twilioからのリクエスト同様にX-Twilio-Signatureを生成してヘッダーに付与することで、ACCESS CONTROLをONにしながらセキュアなアクセスが可能となります。


X-Twilio-Signatureの生成例

以下のコードは、Node.jsを使って、X-Twilio-Signatureを生成するサンプルです。


Node.js

// Get twilio-node from twilio.com/docs/libraries/node

const crypto = require('crypto');

// Your Auth Token from twilio.com/console
const authToken = 'YOUR_AUTH_TOKEN';

// FunctionsのURL
let url = '呼び出したいFunctionsのURL';

// POSTパラメータ
const params = {
test: 'hogehoge'
};

// パラメータを並び替えて、URLに連結した文字列を生成
Object.keys(params).sort().forEach(function(key) {
url = url + key + params[key];
});

// X-Twilio-Signatureの生成
const signature = crypto.createHmac('sha1', authToken).update(new Buffer(url, 'utf-8')).digest('Base64');

console.log(signature);


このようにして生成したX-Twilio-SignatureをFunctionsの呼び出し時にPOSTヘッダーに入れてあげることで、外部から呼び出す際のセキュリティ対策となります。ちなみにSignatureが違っている場合は、呼び出しが403エラーとなります。