概要
本記事は AWSでWebアプリを構築してみる シリーズの9回目の記事です。
前回の記事は こちら。
本記事で作成する構成
前回までの構成は、CloudFrontを経由して構築した静的ウェブサイトおよびREST APIに誰でもアクセスできる状態です。今回は、認証を設けて認証したユーザーのみが利用できるようにしてみます。
静的ウェブサイトおよびREST APIを認証してから利用できるようにしてみる
1. Cognito からユーザープールを作成する
-
マネジメントコンソールから Cognito を開き、「ユーザープールを作成」ボタンをクリック
-
サインインエクスペリエンスの設定はWebアプリの仕様に合わせて設定しますが、このWebアプリでは、プロバイダータイプは「Cognitoユーザープール」、Cognito ユーザープールのサインインオプションは「Eメール」のみを選択するとしました
-
セキュリティ要件の設定はWebアプリの仕様に合わせて設定しますが、このWebアプリでは、パスワードポリシーは「Cognitoのデフォルト」、多要素認証は「MFAなし」、ユーザーアカウントの復旧は無効化としました
-
サインアップエクスペリエンスを設定はWebアプリの仕様に合わせて設定しますが、このWebアプリでは、自己登録を無効化としました
-
メッセージ配信を設定はWebアプリの仕様に合わせて設定しますが、このWebアプリでは、Eメールプロバイダーを「CognitoでEメールを送信」、送信元Eメールアドレスはデフォルトの「no-reply@verficationemail.com」としました
-
アプリケーションを統合ではWebアプリの仕様に合わせて設定しますが、このWebアプリでは以下のように設定した
- ユーザープール名:任意
- ホストされた認証ページ:チェックあり
- ドメイン:
- ドメインタイプ:Cognitoドメインを使用する
- Cognitoドメイン:任意
- 最初のアプリケーションクライアント:
- アプリケーションタイプ:パブリッククライアント
- アプリケーションクライアント名:任意
- 許可されているコールバックURL:CloudFrontのディストリビューションドメイン名を設定(例:https://xxxxx.cloudfront.net)
-
以上の設定より、ユーザープールを作成する
ユーザープールにユーザーを作成する
-
作成したユーザープールを開き、ユーザータブから「ユーザーを作成」ボタンをクリックする
-
任意のメールアドレスとパスワードを設定して、ユーザーを作成する
-
この後で必要になるユーザープールID(作成したユーザープールの概要欄)とクライアントID(作成したユーザープールのアプリケーションの統合タブ内のアプリクライアントと分析欄)とCognitoドメイン(作成したユーザープールのアプリケーションの統合タブ内のドメイン欄)をメモしておく
Cognito ID プール (フェデレーティッド ID)を作成する
-
サイドメニューにあるIDプールから「IDプールを作成」ボタンをクリックする
-
IDプールの信頼を設定では、Webアプリの仕様に合わせて設定しますが、このWebアプリでは以下のように設定
- ユーザーアクセス:認証されたアクセス
- 認証されたIDソース:Amazon Cognitoユーザープール
-
許可を設定では、Webアプリの仕様に合わせて設定しますが、このWebアプリでは以下のように設定
- IAMロール:新しいIAMロールを作成
- IAMロール名:任意
-
IDプロバイダーを接続では、Webアプリの仕様に合わせて設定しますが、このWebアプリでは以下のように設定
- ユーザープールID:さきほどメモしたユーザープールIDを選択
- アプリクライアントID:さきほどメモしたアプリクライアントIDを選択
-
プロパティを設定では、Webアプリの仕様に合わせて設定しますが、このWebアプリでは以下のように設定
- Name:任意
-
以上の設定でIDプールを作成
-
作成したユーザープールを開き、アプリケーションを統合タブからアプリクライアントと分析にある、作成したアプリクライアントのリンクをクリックし、「ホストされたUIを表示」をクリックし、作成したユーザーでサインインすると、認証してからWebアプリが表示されるようになるが、まだこの状態ではCloudFrontからは直接Webアプリが表示できてしまうため、次はLambda@Edgeを作成する
Lambda@Edge作成前の準備
cognito-at-edge に記載されている手順に従ってZIPファイルを作成します。
-
以下のコマンドを実行し、index.jsにCognitoのユーザプールの情報を記述して簡単なハンドラを作成する
npm init npm install cognito-at-edge touch index.js
-
index.js
const { Authenticator } = require('cognito-at-edge'); const authenticator = new Authenticator({ // Replace these parameter values with those of your own environment region: 'us-east-1', userPoolId: 'メモしたユーザープールID', userPoolAppId: 'メモしたアプリクライアントID', userPoolDomain: 'メモしたドメイン', cookiePath: '/', }); exports.handler = async (request) => authenticator.handle(request);
-
ZIPファイルを作成するが、1MBを超えると Lambda@Edge のパッケージのサイズ上限にひっかるため こちら を参考に不要なファイルを削除してZIPを作成する
find -name "*.map" | xargs rm -rf find -type d -name "test" | xargs rm -rf zip -r pkg.zip .
-
Lambda@Edgeを作成する
-
マネジメントコンソールから Lambda を開き、リージョンを「バージニア北部」に変更する(Lambda@Edgeのデプロイはバージニア北部のみであるため)
-
以下の内容で関数を作成する
- 一から作成
- 関数名:任意
- ランタイム:今回は Node.js 20.x
- アーキテクチャ:今回は x86_64
- 実行ロール:AWS ポリシーテンプレートから新しいロールを作成
- ロール名:任意
- ポリシーテンプレート:基本的なLambda@Edgeのアクセス制限(CloudFrontトリガーの場合)
-
コードタブからZIPファイルをアップロードする
-
設定タブのアクセス権限からCloudFrontトリガーを使用するためのLambda実行ロールの編集を行う
-
アクションのLambda@Edgeへのデプロイをクリックし、以下の設定でデプロイする
- オプションの選択:新しい CloudFront トリガーの設定
- ディストリビューション:作成済みのCloudFrontディストリビューション
- CloudFrontイベント:ビューアーリクエスト(解説は こちら を参照)
- ボディを含める:チェックあり
- Lambda@Edgeへのデプロイを確認:チェックあり
-
マネジメントコンソールから CloudFront を開き、作成済みのCloudFrontのビヘイビアを開き、デフォルト (*)のビヘイビアを編集し、関数の関連付けの内容をメモしておく
-
同様に、/api/*のビヘイビアを編集し、メモして内容と同じく設定する
動作確認
以上の設定により、静的ウェブサイトおよびREST APIに対して認証しないと利用できなくなりました。
静的ウェブサイトをCloudFront経由のアクセスしか許可しないようにしてみる で作成したディストリビューションの一般タブを開き、「ディストリビューションドメイン名」をコピーしてブラウザで開き、アクセスしたときに以下のような認証を伴うようになります(シークレットウィンドウで開いてみてください)。