ENGINEER BLOG ENGINEER BLOG
  • 公開日
  • 最終更新日

【CloudFront】awslabs/cognito-at-edgeを使って認証付きでS3オブジェクトを配信する

この記事を共有する

目次

はじめに

皆さんこんにちは!パーソル&サーバーワークスの三宅です。

今回は、AWSが提供している「cognito-at-edge」というNode.jsパッケージを活用し、Amazon CloudFront(以下、CloudFront)とAWS Lambda(以下、Lambda)でAmazon Cognito(以下、Cognito)の認証機能を実装し、認証済みのユーザーだけがS3オブジェクトにアクセスできる仕組みを構築してみます。 CloudFrontでは直接Cognitoと連携することができないため、エッジロケーションでLambda関数を実行できる機能(以下、Lambda@Edge)を通じてCognito認証を実装します。

GitHub - awslabs/cognito-at-edge: Serverless authentication solution to protect your website or Amplify application

本パッケージの説明は以下の通りです。

Cognito認証により、CloudFrontとLambda@Edgeでウェブサイトを簡単に保護できます。 このNode.jsパッケージは、CloudFrontディストリビューションにリクエストを行うユーザーがCognitoユーザープールを使用して認証されていることを確認するのに役立ちます。リクエストに含まれるCookieを調べることでこれを実現し、リクエスターが認証されていない場合は、ユーザープールのログインページにリダイレクトされます。

事前準備

本記事では、Cognito認証の実装に焦点を当てるため、以下のリソースは設定済みとして進めます。

S3バケットとコンテンツの配置

認証対象となるコンテンツを、あらかじめAmazon S3(以下、S3)にバケットに配置しています。

cognito-at-edge_1.png

CloudFrontディストリビューションの設定

S3をオリジンとするCloudFrontディストリビューションを作成済みです。

cognito-at-edge_2.png

試してみた

Cognitoの設定

まず、Cognitoユーザープールを作成し、ユーザー登録・認証を担うディレクトリを準備します。
ユーザープールの作成には、CLIで以下のコマンドを実行します。

aws cognito-idp create-user-pool \
  --pool-name <ユーザープール名> \
  --username-attributes email \
  --auto-verified-attributes email

次に、アプリケーションクライアントを作成します。 コールバックURLの設定には、事前準備で作成したCloudFrontのドメイン名を指定してください。

aws cognito-idp create-user-pool-client \
  --user-pool-id <ユーザープールID> \
  --client-name <アプリケーションクライアント名> \
  --allowed-o-auth-flows code \
  --allowed-o-auth-scopes openid email profile \
  --allowed-o-auth-flows-user-pool-client \
  --callback-urls '["https://CloudFrontのドメイン名"]'

Lambda@Edgeの設定

認証処理を行うLambda@Edge用の関数を作成します。Lambda@Edge関数は必ずus-east-1リージョンで作成してください。
Lambda実行ロールにはLambda@Edge用のポリシーテンプレートを選択します。

cognito-at-edge_5.png

続いて、必要なNode.jsパッケージをインストールし、デプロイ用のzipファイルを作成します。

mkdir cognito-at-edge-test
cd cognito-at-edge-test
npm install cognito-at-edge
vi index.js
zip -r cognito-at-edge-test.zip *

index.jsの内容は以下のとおりです。各パラメータは環境に合わせて適切な値に置き換えてください。

const { Authenticator } = require('cognito-at-edge');
const authenticator = new Authenticator({
  // Replace these parameter values with those of your own environment
  region: '<ユーザープールを作成したリージョン>', // user pool region
  userPoolId: '<ユーザープールID>', // user pool ID
  userPoolAppId: '<アプリケーションクライアントID>', // user pool app client ID
  userPoolDomain: '', // user pool domain
});
exports.handler = async (request) => authenticator.handle(request);

作成したzipファイルをLambda関数にデプロイします。

aws lambda update-function-code \
  --region us-east-1 \
  --function-name cognito-at-edge-test-function \
  --zip-file fileb://cognito-at-edge-test.zip \
  --publish

新しいバージョンを発行し、ARNを取得します。

aws lambda publish-version \
  --region us-east-1 \
  --function-name cognito-at-edge-test-function

返されるARNは以下のような形式になります。このARNは次のステップで使用するため、控えておいてください。

arn:aws:lambda:us-east-1:xxxxxxxxx:function:cognito-at-edge-test-function:1

Lambda@Edgeの注意点については、以前の記事で詳しく解説していますので、気になる方はぜひご参照ください。
参考記事:【Lambda@Edge】初心者がハマりがちな落とし穴6選

CloudFrontとLambda@Edgeの関連付け

CloudFrontのビヘイビア設定で、先ほど発行したバージョンのARNを「ビューワーリクエスト」に関連付けて保存します。
CloudFrontのデプロイには5~10分程度の時間がかかります。

cognito-at-edge_13.png

動作確認

ブラウザでCloudFront経由でコンテンツにアクセスすると、未認証ユーザーは自動的にCognito Hosted UIのログインページへリダイレクトされます。 初回アクセスの場合は、「サインアップ」から新しいユーザーを登録してください。

cognito-at-edge_8.png

ログインが成功すると、セッション情報がCookieに保存され、S3オブジェクトが正しく配信されることを確認できます。

cognito-at-edge_11.png

まとめ

今回は、AWSがGitHubで公開している「cognito-at-edge」パッケージを活用して、CloudFront + Lambda@Edge + Cognitoによる認証機能を構築しました。 このパッケージを利用することで、比較的簡単に認証フローを実現できました。 静的コンテンツに手軽に認証機能を追加したい場合や、S3上のプライベートコンテンツを特定のユーザーにのみ公開したい場合に、非常に有効なのでLambda@Edgeの制限事項に注意しながら、ぜひ活用してみてください。

この記事は私が書きました

三宅 啓右

記事一覧

2025 Japan All AWS Certifications Engineers 猫派でしたが最近犬派になりました。

三宅 啓右

この記事を共有する

クラウドのご相談

CONTACT

クラウド導入や運用でお悩みの方は、お気軽にご相談ください。
専門家がサポートします。

サービス資料ダウンロード

DOWNLOAD

ビジネスをクラウドで加速させる準備はできていますか?
今すぐサービス資料をダウンロードして、詳細をご確認ください。