1. ホーム
  2. 記事一覧
  3. 【ハンズオン】Amazon S3にホストされた静的サイトにCognitoを用いた認証を追加

2024.04.17

【ハンズオン】Amazon S3にホストされた静的サイトにCognitoを用いた認証を追加

このハンズオンで学べること

このハンズオンでは、Amazon Web Services(AWS)のサービスを活用して、静的ウェブサイトに安全なユーザー認証機能を実装する方法を学んでいきます。Cognitoを利用した安全な認証システムを構築し、読者だけに記事や動画を限定公開することができるようになります。

具体的には、Amazon S3にホストされたウェブサイトにAmazon Cognitoを使用して、ユーザー登録とログイン機能を実装する手順を詳細に説明します。このプロジェクトを通して、以下の内容を学び、実践することができます。

  • Amazon Cognitoの設定

    ユーザープールの作成と管理方法

  • AWSとの連携

    S3バケットのセットアップと静的ファイルのデプロイ、Cognitoを利用した認証機能のウェブサイトへの統合

  • セキュリティ強化

    HTTPSを利用したセキュアなウェブサイトの構築(オプション)

必要な前提知識

基本的な手順は初心者の方にも分かりやすく説明します。 このハンズオンを最大限に理解するために、以下の知識があると役立ちます。

  • HTML/CSS/JavaScript

    静的ウェブページの作成と編集ができるレベル

  • AWSアカウント

    実際にAWSのリソースを使用するためにはアカウントが必要です。

  • AWSの基本的な操作

    AWS Management Consoleの基本的な操作に慣れていることが望ましい

必要なツールとサービス

  • Amazon S3
  • Amazon Cognito

Amazon Cognitoユーザープールの設定

Amazon Cognitoは、ユーザーのサインアップ、サインイン、アクセスコントロールなどを管理するサービスです。このステップでは、Amazon Cognitoのユーザープールを設定して、ウェブサイトでのユーザー認証機能を実装する準備を行います。

1. Cognitoユーザープールの作成

まず、新しいユーザープールを作成します。これにより、登録されたユーザーがウェブサイトにログインできるようになります。

  1. AWS Management Consoleにログインし、「Cognito」を検索してサービスページにアクセスします。

  2. 「ユーザープールの作成」画面で「サインインエクスペリエンスを設定」していきます。プロバイダーのタイプは「Cognitoユーザープール」です。

  3. 「Cognitoユーザープールのサインインオプション」で「ユーザー名」にチェックを入れ「次へ」を押下します。

  4. 「セキュリティ要件を設定」画面では、今回は検証のため「他要素認証」にて「MFAなし」を選択し「次へ」を押下します。

  5. 「サインアップエクスペリエンスを設定」画面はデフォルトのまま「次へ」

  6. 「メッセージ配信を設定」画面では、今回は検証のため「Eメールプロバイダー」を「CognitoでEメールを送信」に変更し「次へ」

  7. ユーザープールが作成されたら、プールIDが表示されます。これは後のステップで必要となるので、記録しておきましょう。

2. アプリケーションを統合

ウェブサイトと連携させるためのアプリクライアントを設定します。

  1. 「ユーザープール名」に「MyExampleUserPool」と入力します。
  2. 「アプリクライアント名」に「MyExampleWebClient」と入力します。セキュリティの観点から、クライアントシークレットは生成しないことを推奨します。「次へ」を押下します。
  3. 「確認及び作成」で問題なければ、「ユーザープールを作成」をクリックして設定を完了します。

3. ユーザープールの詳細(クライアントIDなど)の確認

最後に、ユーザープール、アプリケーションの統合タブで詳細情報を確認します。

  1. Cognitoのダッシュボードに戻り、作成したユーザープールの名前をクリックします。
  2. 「ユーザープールの概要」と「アプリケーションの統合」タブで、プールIDやアプリクライアントIDなどの重要な情報を再確認します。

以上で、Amazon Cognitoユーザープールの設定は完了です。次のステップでは、これらの設定を使用して、実際にS3でホストされる静的サイトに認証機能を組み込みます。

Amazon S3で静的ウェブサイトをホスティング

このステップでは、Amazon S3に静的サイトをホストするためのバケットを設定し、必要なHTML、CSS、およびJavaScriptファイルをアップロードします。その後、サイトが正しくアクセスできるかをテストします。

1. S3バケットの作成と公開設定

まず、新しいS3バケットを作成し、ウェブサイト用に公開設定を行います。

AWS Management Consoleでの設定:

  1. AWS管理コンソールにログインし、「S3」を検索してサービスページにアクセスします。
  2. 「バケットを作成する」をクリックし、バケット名を指定します(例: myexamplestaticsite)。バケット名はグローバルで一意である必要があります。
  3. 「パブリックアクセスを全てブロック」のチェックを解除し、バケットが公開されるように設定します。
  4. 「現在の設定により、このバケットとバケット内のオブジェクトが公開される可能性があることを承認します。」にチェックを入れます。
  5. 「バケットの作成」を押下します。

静的ウェブホスティングの有効化

バケット作成後、バケットポリシーを設定して静的ウェブホスティングを有効にします。

  1. バケット一覧から、作成したバケット名をクリック。
  2. 「アクセス許可」タブから「バケットポリシー」を次のように「編集」。

バケットポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::myexamplestaticsite/*"
        }
    ]
}

そして、「プロパティ」タブから「静的ウェブサイトホスティング」を「編集」し、インデックスドキュメントとしてindex.htmlを指定し「変更の保存」します。

2. 静的ファイル(HTML, CSS, JS)のアップロード

次に、以下のサンプルコードを使用してHTML, CSS, および JavaScriptファイルを作成し、S3バケットにアップロードします。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>サンプルサイトへようこそ!</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <h1>サンプルサイトへようこそ!</h1>
    <p>専用コンテンツにアクセスするには、ログインしてください。</p>
    <div id="login"></div>
    <script src="app.js"></script>
</body>
</html>

style.css

body {
    font-family: Arial, sans-serif;
    line-height: 1.6;
    margin: 40px;
}

h1 {
    color: #333;
}

app.js

document.getElementById('login').innerHTML = '<button onclick="handleLogin()">Login</button>';

function handleLogin() {
    // ログイン処理
    alert('Login functionality will be implemented here.');
}

これらのファイルを作成し、S3バケットにアップロードします。

3. サイトアクセスのテスト

最後に、バケットで静的ウェブサイトホスティングが有効になっていることを確認し、表示されたエンドポイントURL(バケットプロパティの「静的ウェブサイトホスティング」セクションに表示)でサイトにアクセスします。サイトが正しく表示されるか確認してください。

認証機能の組み込み

AWS SDK for JavaScriptのライブラリを活用し、Amazon Cognito と連携することで、ウェブサイトに安全な認証機能を構築します。ユーザーはログイン後、保護されたコンテンツにアクセス可能となります。

1. AWS SDK for JavaScriptの導入

AWS SDK for JavaScriptは、AWSサービスを簡単に利用できるようにするJavaScriptライブラリです。これを使用してCognito認証を組み込みます。

まず、ウェブページに次のライブラリを2つとも含めます。以下のスクリプトタグをindex.html<head>セクションに追加してください。

<!-- Amazon Cognito Identity SDK -->
<script src="https://unpkg.com/amazon-cognito-identity-js/dist/amazon-cognito-identity.min.js"></script>

2. ログインページの作成

ログインフォームをindex.htmlに追加します。これは、ユーザーがログイン情報を入力するためのインターフェースを提供します。 次のコードを<div id="login"></div>と置き換えてください。

<!-- ログインセクション -->
<section id="login">
    <h2>ログイン</h2>
    <form id="loginForm">
        <input type="text" id="username" placeholder="ユーザー名" required>
        <input type="password" id="password" placeholder="パスワード" required>
        <button type="submit">ログイン</button>
    </form>
    <p id="loginMessage"></p>
</section>  

3. Cognitoと連携するJavaScriptコードの追加

ライブラリを使用して、Cognitoユーザープールとの連携を設定します。app.jsを次のコードに書き換えてください。 今回はハンズオンのため、UserPoolIdとClientIdをハードコードしてます。これは、セキュリティ的に問題があるため、外部ファイルにするなどして対応してください。

また、Cognito上でユーザーを作成した場合、初回はパスワードを変更する必要があります。今回はパスワード変更の仕組みを準備していないため、newPasswordRequiredの部分で仮パスワード(Password-1)を設定しています。本来はパスワード変更する仕組みを実装するのが望ましいです。

document.addEventListener('DOMContentLoaded', function() {
    var signInForm = document.getElementById('loginForm');

    signInForm.addEventListener('submit', function(event) {
        event.preventDefault();
        var username = document.getElementById('username').value;
        var password = document.getElementById('password').value;
        // 下記の値のハードコードは推奨されません
        var poolData = {
            UserPoolId: 'ap-northeast-1_XXXXXXXXX',
            ClientId: 'XXXXXXXXXXXXXXXXXXXXXXXXXX'
        };
        var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
        var userData = {
            Username: username,
            Pool: userPool
        };
        var authenticationData = {
            Username: username,
            Password: password
        };
        var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(authenticationData);
        var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
        
        cognitoUser.authenticateUser(authenticationDetails, {
            onSuccess: function(result) {
                document.getElementById('loginMessage').innerText = 'ログインに成功しました。';
                console.log('access token + ' + result.getAccessToken().getJwtToken());
            },
            onFailure: function(err) {
                document.getElementById('loginMessage').innerText = 'ログインに失敗しました: ' + err.message;
                alert(err.message || JSON.stringify(err));
            },
            // 初回パスワード変更が必要なため、新しいパスワードを設定する
            newPasswordRequired: function (userAttributes, requiredAttributes) {
                cognitoUser.completeNewPasswordChallenge(config.Password-1, {}, this);
            }
        });
    });
});

このコードは、ユーザーがフォームに入力したユーザー名とパスワードを使用してログインを試み、結果を表示します。

4. 認証フローのテスト

すべてのコードが追加された後、ウェブサイトを再度S3にアップロードし、S3の静的ウェブサイトURLからアクセスしてログイン機能をテストします。 正しく設定されていれば、ユーザーはログインフォームを使用してサイトにログインできます。 認証の成功と失敗の両方をテストして、エラーハンドリングが適切に機能しているか確認してください。

以上で、Amazon Cognitoを用いた認証システムが静的サイトに組み込まれました。次は、このシステムを使用して特定のコンテンツへのアクセスを制限するなど、さらに拡張することが可能です。

本来の実装について

この記事では、Amazon S3を使用して静的ウェブサイトをホスティングし、Amazon Cognitoを通じて基本的な認証プロセスを組み込む方法を説明しました。しかし、認証後にアクセスを許可するコンテンツの管理や、異なるページでのセキュアなルーティングなど、さらに詳細なセキュリティ対策が必要な場合があります。これらは通常、アプリケーションを構成する複数のページにわたって実施されます。

本来のアプローチとその利点

理想的には、ウェブサイトは複数のページから構成され、各ページが特定の役割を担います。例えば次のようなものがあります。

  • ログインページ

    ユーザーが認証情報を入力し、ログインを試みるページ。

  • ダッシュボードページ

    認証されたユーザーのみがアクセス可能な、ユーザー情報やその他のセキュアなコンテンツを表示するページ。

  • エラーページ

    認証が失敗した場合や、アクセス権限がないコンテンツにアクセスしようとした際に表示されるページ。

別の記事で、これらの異なるコンポーネントを持つウェブサイトを構築する方法を詳しく説明します。

今回のハンズオンのまとめ

この記事では、Amazon S3を利用した静的ウェブサイトホスティングと、Amazon Cognitoを使った基本的な認証プロセスの組み込みについて解説しました。少ないリソースと時間で実装できることが理解いただけたかと思います。

  • Amazon Cognito ユーザープールの設定

    ユーザーの認証情報を管理するために必要な設定を行いました。

  • S3バケットの設定と静的サイトのホスティング

    静的ファイルのアップロードと公開設定を完了し、ウェブサイトを公開しました。

  • 認証機能の組み込み

    AWS Amplify LibraryとJavaScriptを使ってログイン機能を実装し、認証されたユーザーがコンテンツを見ることができるようにしました。

今回の記事ではボリュームが大きくなりすぎることから、一つのページのみのシンプルな実装に留まりました。本格的なウェブアプリケーションでは、複数のページと高度なセキュリティ対策が必要です。次回のCognitoハンズオン記事では、より複雑なシナリオに対応するため、異なるページにわたる認証フローと、セキュアなコンテンツの管理について詳しく取り上げます。

エンベーダー編集部

エンベーダーは、ITスクールRareTECHのインフラ学習教材として誕生しました。 「遊びながらインフラエンジニアへ」をコンセプトに、インフラへの学習ハードルを下げるツールとして運営されています。

RareTECH 無料体験授業開催中! オンラインにて実施中! Top10%のエンジニアになる秘訣を伝授します! RareTECH講師への質疑応答可

関連記事

2020.02.25

完全未経験からエンジニアを目指す爆速勉強法

USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話

  • キャリア・学習法
  • エンジニア

2024.04.06

[ハンズオン]AWS Backupで作成したAMIをLambdaを使用して起動テンプレートに適用

この記事では、AWS上でのリソース管理を自動化する方法を実践的に解説します。特に、開発環境やプロダクション環境におけるデプロイメントプロセスの簡素化や、ディザスタリカバリ準備の一環として、最新のAMIを定期的に起動テンプレートに適用する自動化手法を紹介します。

  • AWS
  • インフラエンジニア
  • ハンズオン

2024.04.30

Koa.jsの解説と導入ハンズオン Express.jsの後継フレームワーク

Koa.jsはその軽量性とモダンなJavaScriptの特性を活用する設計により、Web開発者に高いパフォーマンスと優れたエラー処理能力を提供し、注目を集めています。Express.jsの開発者により作られ、最小構成で柔軟性に富むオープンソースのNode.js用Webフレームワークです。

  • Node.js
  • ハンズオン
  • フレームワーク

2023.11.21

【Part 3/4】AWSの環境構築で学ぶトラブルシューティング【Route53】

今回は、Route53を使用し、特定のインスタンスにドメインでアクセスできるようにする環境を構築します。AWSのプライベートネットワークを介した安全な通信を利用する方法を学習します。

  • AWS