はじめに
今回は、キャンペーンサイトなどでよくある「特定の時間になったらページを非公開にしたい」という要件を、CloudFront Functionsを使って簡単でシンプルに実現する方法についてです。
サーバーレスで、かつEventBridge スケジューラ(Cron)やStep Functionsのようなスケジュール実行サービスも使わない構成です。
解決策:CloudFront Functionsで「ゲート」を設置する
ビューワーリクエストにCloudFront Functionsを指定して、ゲートとして設置します。
Basic認証などで使用する方もいらっしゃるのではないでしょうか。
仕組みは、Webコンテンツ(S3など)の手前にあるCloudFrontに、時刻をチェックする門番を設置するイメージです。
- 実行場所: AWSのサーバー上(エッジロケーション)
- 時刻の基準: UTC(協定世界時)
補足:日本時間(JST)からUTCへの変換
日本時間(JST)はUTCより9時間進んでいます (UTC+9
)。
そのため、UTCの時刻を計算するには日本時間から9時間を引きます。
- 例1: JST
9月30日 09:00
→09 - 9 = 0
→ UTC9月30日 00:00
- 例2: JST
10月1日 08:00
→08 - 9 = -1
→ UTC9月30日 23:00
(日付が前日になる)
ここは非常に重要なので、慎重に行いましょう。
実装
それでは、実際に関数を設定していきます。
1. CloudFront Functionの作成
AWSコンソールからCloudFrontのダッシュボードを開き、サイドメニューの「関数」に遷移
「関数の作成」をクリック
関数名(例: block-access-by-time
)を入力して作成します。
2. コードの記述
作成した関数の「ビルド」タブを開き、関数コードを記述。
今回は、**日本時間で2025/8/31 23:59:59を期限に設定するコードです。
ご自身の要件に合わせてexpirationDate
の値を書き換えてください。
async function handler(event) {
// --- 締切時刻の設定 ---
const expirationDate = new Date('2025-08-31T014:59:59Z');
const currentDate = new Date();
// 現在日時が指定日時を過ぎていたらアクセスを拒否 (403 Forbidden)
if (currentDate > expirationDate) {
return {
statusCode: 403,
statusDescription: 'Forbidden'
};
}
// 指定日時より前なら、通常通りリクエストを返す
return event.request;
}
コードを貼り付けたら、「変更を保存」します。
3. 関数の発行
「発行」タブに移動し、「関数を発行」をクリックします。
これで、作成した関数をディストリビューションに関連付けられるようになります。
4. ディストリビューションへの関連付け
最後に、この関数をWebサイトに適用します。
対象のCloudFrontのディストリビューションを選択し、「ビヘイビア」タブから該当のビヘイビアを編集します。
画面下部の「関数の関連付け」で、以下のように設定します。
- ビュワーリクエスト - イベントタイプ:
Viewer Request
- ビュワーリクエスト - 関数ARN:
CloudFront Functions
を選択し、先ほど作成した関数(例:block-access-by-time)を選びます
設定後、「変更を保存」を押して完了です。数分で設定が反映されます。
時刻指定の落とし穴「タイムゾーン」
以前、「日本時間の午前0時にページを開けないように」という機能を実装した際、時刻の判定をフロントエンド(ブラウザのJavaScript)で行っていました。
その結果、日本で締切時刻を過ぎているのに、時差のある海外からのユーザーはまだアクセスができてしまうという事象が発生しました。これは、ブラウザでnew Date()
を実行すると、ユーザーのPCに設定されたローカルタイムゾーンを基準に時刻を解釈してしまうためです。
今回はサーバー側で時刻の判定を行うのでこの問題も回避できます。
最後に
今回はCloudFront Functionsを使い、シンプルかつ正確にアクセス制御を行う方法を解説しました。
サーバーレスでコストもほとんどかからず、何よりタイムゾーンの問題を気にしなくてよいのが大きなメリットです。
キャンペーンサイトの公開終了などでぜひ活用してみてください。