【Node.js】 CloudFront にきた特定ホスト向けのリクエストを、 Lambda@Edgeで URI を維持しながらリダイレクトするコードを書いてみる

記事タイトルとURLをコピーする

はじめに

CloudFront にきた特定ホスト向けのリクエストを、 Lambda@Edge(以後L@E) で URI を維持しながらリダイレクトするコードを Node.js で書いてみました。

記事目安...5分~10分

コードについて

'use strict';

// Input Redirect source URL & Redirect URL.
const redirectSrcHost = 'hogehoge.com';
const redirectHost = 'www.hogehoge.com';

exports.handler = (event, context, callback) => {
    
    const originalRequest = event.Records[0].cf.request;   

    //Extact require param from "originalRequest".
    const originalHost = originalRequest.headers.host[0].value;
    const originalUri = originalRequest.uri;
    
    // response to User or Origin.
    if (originalHost == redirectSrcHost){

        //Generate HTTP redirect response.
        const redirectResponse = {
            status: '301',
            statusDescription: 'Redirect',
            headers: {
            'location': [{
                key: 'Location',
                value: 'https://' + redirectHost + originalUri,
            }],
            },
        };

        callback(null, redirectResponse);
    } else {
        callback(null, originalRequest)
    }
};

サンプルでは、URI を維持したまま hogehoge.comwww.hogehoge.com にリダイレクトします。

hogehoge.com 以外のホスト名指定でリクエストが来た場合は、オリジンにリクエストを通します。

使い方

STEP1. コードを変更する

  • redirectSrcHost にリダイレクト元のホスト名を挿入します
const redirectSrcHost = 'hogehoge.com';
  • redirectHost にリダイレクト先のホスト名を挿入します
const redirectHost = 'www.hogehoge.com';

STEP2. L@E をデプロイする

デプロイの詳細手順は省きますが、
L@E の処理をキャッシュしたい場合は、 オリジンリクエスト にデプロイしてください。

テスト用リクエストについて

Lambda でのテストで使用したリクエストの Json もおいておきます。


パターン1: hogehoge.com へリクエストを投げた場合

{
  "Records": [
    {
      "cf": {
        "config": {
          "distributionDomainName": "d111111abcdef8.cloudfront.net",
          "distributionId": "EDFDVBD6EXAMPLE",
          "eventType": "origin-request",
          "requestId": "4TyzHTaYWb1GX1qTfsHhEqV6HUDd_BzoBZnwfnvQc_1oF26ClkoUSEQ=="
        },
        "request": {
          "clientIp": "203.0.113.178",
          "headers": {
            "x-forwarded-for": [
              {
                "key": "X-Forwarded-For",
                "value": "203.0.113.178"
              }
            ],
            "user-agent": [
              {
                "key": "User-Agent",
                "value": "Amazon CloudFront"
              }
            ],
            "via": [
              {
                "key": "Via",
                "value": "2.0 2afae0d44e2540f472c0635ab62c232b.cloudfront.net (CloudFront)"
              }
            ],
            "host": [
              {
                "key": "Host",
                "value": "hogehoge.com"
              }
            ],
            "cache-control": [
              {
                "key": "Cache-Control",
                "value": "no-cache, cf-no-cache"
              }
            ]
          },
          "method": "GET",
          "origin": {
            "custom": {
              "customHeaders": {},
              "domainName": "hogehoge.com",
              "keepaliveTimeout": 5,
              "path": "",
              "port": 443,
              "protocol": "https",
              "readTimeout": 30,
              "sslProtocols": [
                "TLSv1",
                "TLSv1.1",
                "TLSv1.2"
              ]
            }
          },
          "querystring": "",
          "uri": "/test"
        }
      }
    }
  ]
}

パターン2: fugafuga.hogehoge.com へリクエストを投げた場合

{
  "Records": [
    {
      "cf": {
        "config": {
          "distributionDomainName": "d111111abcdef8.cloudfront.net",
          "distributionId": "EDFDVBD6EXAMPLE",
          "eventType": "origin-request",
          "requestId": "4TyzHTaYWb1GX1qTfsHhEqV6HUDd_BzoBZnwfnvQc_1oF26ClkoUSEQ=="
        },
        "request": {
          "clientIp": "203.0.113.178",
          "headers": {
            "x-forwarded-for": [
              {
                "key": "X-Forwarded-For",
                "value": "203.0.113.178"
              }
            ],
            "user-agent": [
              {
                "key": "User-Agent",
                "value": "Amazon CloudFront"
              }
            ],
            "via": [
              {
                "key": "Via",
                "value": "2.0 2afae0d44e2540f472c0635ab62c232b.cloudfront.net (CloudFront)"
              }
            ],
            "host": [
              {
                "key": "Host",
                "value": "fugafuga.hogehoge.com"
              }
            ],
            "cache-control": [
              {
                "key": "Cache-Control",
                "value": "no-cache, cf-no-cache"
              }
            ]
          },
          "method": "GET",
          "origin": {
            "custom": {
              "customHeaders": {},
              "domainName": "fugafuga.hogehoge.com",
              "keepaliveTimeout": 5,
              "path": "",
              "port": 443,
              "protocol": "https",
              "readTimeout": 30,
              "sslProtocols": [
                "TLSv1",
                "TLSv1.1",
                "TLSv1.2"
              ]
            }
          },
          "querystring": "",
          "uri": "/test"
        }
      }
    }
  ]
}

参考: Lambda@Edge イベント構造 - Amazon CloudFront -オリジンリクエストの例

参考

菅谷 歩 (記事一覧)