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ハンズオン記事では、より複雑なシナリオに対応するため、異なるページにわたる認証フローと、セキュアなコンテンツの管理について詳しく取り上げます。

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

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

プログラミング塾に半年通えば、一人前になれると思っているあなた。それ、勘違いですよ。「なぜ間違いなの?」「正しい勉強法とは何なの?」ITを学び始める全ての人に知って欲しい。そう思って書きました。是非読んでみてください。

「フリーランスエンジニア」

近年やっと世間に浸透した言葉だ。ひと昔まえ、終身雇用は当たり前で、大企業に就職することは一種のステータスだった。しかし、そんな時代も終わり「優秀な人材は転職する」ことが当たり前の時代となる。フリーランスエンジニアに高価値が付く現在、ネットを見ると「未経験でも年収400万以上」などと書いてある。これに釣られて、多くの人がフリーランスになろうとITの世界に入ってきている。私もその中の1人だ。数年前、USBも知らない状態からITの世界に没入し、そこから約2年間、毎日勉学を行なった。他人の何十倍も努力した。そして、企業研修やIT塾で数多くの受講生の指導経験も得た。そこで私は、伸びるエンジニアとそうでないエンジニアをたくさん見てきた。そして、稼げるエンジニア、稼げないエンジニアを見てきた。

「成功する人とそうでない人の違いは何か?」

私が出した答えは、「量産型エンジニアか否か」である。今のエンジニア市場には、量産型エンジニアが溢れている!!ここでの量産型エンジニアの定義は以下の通りである。

比較的簡単に学習可能なWebフレームワーク(WordPress, Rails)やPython等の知識はあるが、ITの基本概念を理解していないため、単調な作業しかこなすことができないエンジニアのこと。

多くの人がフリーランスエンジニアを目指す時代に中途半端な知識や技術力でこの世界に飛び込むと返って過酷な労働条件で働くことになる。そこで、エンジニアを目指すあなたがどう学習していくべきかを私の経験を交えて書こうと思った。続きはこちらから、、、、

note記事3000いいね超えの殿堂記事 今すぐ読む

エンベーダー編集部

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

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

関連記事

2020.02.25

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

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

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

2024.06.30

Terraformで構築するWeb2層構造 初心者向けハンズオン

このハンズオンは、AWS上でインフラストラクチャをコードとして管理する方法を学びたい初心者に最適です。

  • AWS
  • ハンズオン

2024.04.06

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

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

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

2024.04.14

手を動かして身につける AWSでサーバレスのハンズオン

サーバレスコンピューティングの最大のメリットは、インフラの管理から解放されることです。開発者はサーバーのプロビジョニングや保守に関する心配をする必要がなく、アプリケーションのコードの作成とその実行に専念できます。より迅速にアプリケーションを市場に投入することが可能となり、イノベーションの速度を高めることができます。

  • AWS
  • ハンズオン