なぜ必要?
XXX.example.com
の XXX
部分によって挙動を変える、つまりサブドメインをパラメータにしたかった。
普通にCloudfront + API GatewayにしてしまうとHostヘッダはAPI Gatewayのもの(xxxxxxx.execute-api.ap-northeast-1.amazonaws.com)になってしまいます。
これに対し、Cloudfrontに来たHOSTをAPI Gatewayに横流ししてみました。
作業的にはCloudfrontのWhitelist HeadersにHOSTを入れれば解決か?と思ったのですが、これだとAPI Gateway側で証明書検証できず500番台エラーが返ってきてしまいます。。。
ちょっと手こずったので解決方法を残しておきます。
解決の大まかな流れ
- Cloudfrontに来たHOSTをAPI Gateway側に流す
- HOSTそのままではAPI Gatewayに受け入れてもらえないのでHOSTはAPI Gatewayの値に書き換えつつX-FORWARDED-HOSTにアクセス元のHOSTを載せる
1. Cloudfrontに来たHOSTをAPI Gateway側に流す
CloudfrontのWhitelist Headersに値設定するだけです。
以下の2つを設定してください。
HOST
-
X-FORWARDED-HOST
(下記スクリプトと矛盾なければヘッダ名は自由です)
2. HOSTそのままではAPI Gatewayに受け入れてもらえないのでHOSTはAPI Gatewayの値に書き換えつつX-FORWARDED-HOSTにアクセス元のHOSTを載せる
Lambda@Edgeを使ってオリジンへのアクセス時にヘッダを書き換えます。
exports.handler = async (event, context, callback) => {
const request = event.Records[0].cf.request;
const headers = request.headers;
// Hostの値をX-Forwarded-Hostに写す
headers['x-forwarded-host'] = [{
key: 'X-Forwarded-Host',
value: headers.host[0].value
}];
// API GatewayのHOSTに書き換え
headers['host'] = [{
key: 'Host',
value: 'pcwldf375g.execute-api.ap-northeast-1.amazonaws.com'
}];
callback(null, request);
};
このLambdaをCloudfrontのOrigin Request(否Viewer Request!)に設定します。
ここまでできれば受け取り側のLambdaで普通にX-FORWARDED-HOSTヘッダを見ればOKです。めでたしめでたし。