LoginSignup
0
0

More than 3 years have passed since last update.

Lambda@Edge で wwwあり・なしをどちらか一方にリダイレクトで寄せる対処を行う

Last updated at Posted at 2020-10-30

モチベーション

サイトを公開する場合、 www.example.comexample.com の両方でアクセス可能とすることがある (いわゆる、wwwのあり・なし設定)。 ただし、両方のFQDNが有効な場合であっても、SEO効果などの理由から、サーバー側でリダイレクトを行い、1つのFQDNを正としてサイトを運営する方が良い。
これを nginx で「wwwありに寄せる」書く場合は以下のように書く。 なお、現時点でサイトを運営するならば https にすべきだとは思うが、単なる例なのでここでは触れないこととする。

# www ありに寄せる例
server {
    listen      80;
    server_name www.example.com;
    # 以下サイトの設定を記述
}

server {
    listen      80;
    server_name example.com;

    location / {
        return 301 http://www.example.com$request_uri;
    }
}

これと同様のことを CloudFront で行う方法の1つとして、Lambda@Edge を利用した方法を紹介する。

追加モチベーション

これが必要なもう一つの理由としては CloudFront -> API Gateway -> Lambda という構成を採っているのだが、デフォルト設定のままだと Lambda でアクセスしてきたホストを取得できないという問題がある。 そのため、ホスト毎に処理を切り替えたい場合に困ってしまった。
そこで、今回は上記のように、そもそもどちらか一方のみを正とすることで、Lambdaで利用するホスト名を固定値で参照可能とした。

なお Lambda@Edge を使えば上記の構成でも Lambda にホスト名を渡すことはできる。 具体的には以下の記事を参照。

Lambda@Edge でのリダイレクト

どうすればリダイレクトできるかの具体例は公式ページに書いてある。

今回は同じCloudFront ディストリビューションで www.example.comexample.com の両方を受け付け、www.example.com 以外www.example.com にリダイレクトする例 (先述の nginx と同じ例) を示す。 nginxと異なり、こちらではディストリビューションで "http -> https リダイレクト" 設定が行われているものとする。

Python3.8ランタイムでの実行を想定
#!/usr/bin/python
# -*- coding: utf-8 -*-

REDIRECT_HOST = 'www.example.com'


def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']
    headers = request['headers']

    if headers['host'][0]['value'] == REDIRECT_HOST:
        # ホスト名が指定したものであればリダイレクトしない
        return request

    uri = request['uri']
    redirect_response = {
        'status': '301',
        'statusDescription': 'Moved Permanently',
        'headers': {
            'location': [{
                'key': 'Location',
                'value': f'https://{REDIRECT_HOST}{uri}'
            }]
        }
    }

    return redirect_response

これをビュワーリクエストに設定すればよい。 Lambda@Edge の設定方法は 前のベーシック認証を設定する記事 を参照のこと。

別解

今回は1つの CloudFront ディストリビューションで複数の FQDN が有効になっている場合の対処を示した。 一方、1つのFQDNごとに1つのディストリビューションを用意できるのであれば、用意したディストリビューションへの通信の全てをリダイレクトする設定を書けば対処可能である。

具体的には、「Cloudfront ディストリビューションを Web Hosting してリダイレクトルールを記載した S3 バケットに流してリダイレクトさせる」「空のS3に流すが、Lambda@Edgeをビュワーリクエストに記載してここで固定のリダイレクトを行う」などである。

0
0
0

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
0
0