AWS資格取得に向けて実際にAWSを利用してみるシリーズの投稿です。
今回はAWSを使って素早く簡単にユーザーのサインアップ/サインインおよびアクセスコントロールの機能を追加できるAmazon Cognitoを利用してみる編です。1時間程度でCognitoを利用したログイン機能が作成できます。
資格勉強的にはCognitoのユーザープール、IDプールの違いを確認しつつ、手っ取り早くログイン画面の作成するための手順になっています。
興味がある方は読んでみて下さい。
資格試験の勉強法は記事は以下を参照。
AWS初心者がAWS 認定ソリューションアーキテクト – アソシエイト資格試験に合格した時の勉強法
AWS初心者がAWS 認定ソリューションアーキテクト – プロフェッショナル資格試験に合格した時の勉強法
想定読者
- AWSでログイン機能(認証・認可)ができるCognitoを使ってサクッとログイン画面を作りたい人
- Cognitoのユーザープール、IDプールをAWSコンソールで確認して理解を深めたい人
料金
無料利用枠が、Cognito ユーザープールに直接サインインするユーザーの場合は 50,000 MAU、SAML 2.0 ベースの ID プロバイダーを介してフェデレーションされるユーザーの場合は 50 MAU 分あるため、サクッと作って個人で試すだけなら無料で出来るようです。
公式ページ
作業時間
約1時間
完成画面
こんなログイン画面ができます。
※今回は、Cognitoを試すことに目的にしているためデザインは一切ありません^^;
可能な限りシンプルなHTMLとJavaScriptで実現しています。
以下のページを参考にしていますが、さらにシンプルにしてみました。
https://www.tdi.co.jp/miso/amazon-cognito-activation-sign-in
メールアドレスをIDとして使用しており、画面のタイトルの一部に使っているAuthenticateUserは使用しているライブラリでログインするときに使うメソッド名になります。
ログイン画面に加えて、ユーザ(メールアドレスとパスワード)登録画面、メールアドレスの確認(メールアドレス認証)画面も作るので全部で3画面を作成します。
それぞれの画面使っている主要なライブラリメソッドは以下になります。
主要なライブラリメソッド
- ログイン画面
- AmazonCognitoIdentity.CognitoUser authenticateUser メソッド
- ユーザ登録画面
- AmazonCognitoIdentity.CognitoUserPool signUp メソッド
- メールアドレス確認画面
- AmazonCognitoIdentity.CognitoUser confirmRegistration メソッド
ちなみに、ログインに成功するとこんな感じ。
ログイン後に各種AWSサービスにアクセスするために必要な 認証情報(IDトークン/アクセストークン/リフレッシュトークン) をブラウザのコンソールに表示させています。
では、実際に手順に従ってやってみましょう。
参考書籍
Cognitoに特化した書籍はまだないのですが、以下の本はCognitoとAPIGatewayを連携させて認証に使用する解説とかがあって参考になりました。
特徴的なのが今回のような画面操作によってCognitoを使っておらず、AWS CDKを使ってCognitoを構築しているところがすごいです。画面操作だとどうしても画面メニューが変更されると再現性が下がるのですが、AWS CDKを使ってコードで定義しておくと再現性高く構築手順を維持できるのが便利です。
Cognitoに限らずAWSの様々なサービスを使ってアプリを作り上げているハンズオンが有益でサンプルコードも提供されている良い本なのでここで紹介です。
作業手順
作業手順は以下の5つの手順になります。
1、2は AWSコンソール で作成、3~5は HTML/JavaScript実装 になります。
1.AWSコンソール Cognitoからユーザプールの作成
2.AWSコンソール CognitoからIDプールの作成
3.画面実装 ユーザ登録画面(サインアップ画面)作成
4.画面実装 ユーザID(メールアドレス)認証画面作成
5.画面実装 ログイン画面作成
事前準備
AWSアカウントは前提条件として割愛すると、以下を準備すれば事前準備完了です。簡単ですね。
- テキストエディタ/ブラウザ
今回はEclipseのようなIDEは不要なためテキストエディタで実装して、そのままブラウザで動かします。
- CognitoSDKダウンロード
Cognitoとのやり取りにはJavaScriptの以下のSDK(amazon-cognito-identity-js)を使用します。
以下の3つのユースケースをそのまま使っているところがあるのでこちらも参考にしてみてください。
Use case 1. サインアップ
Use case 1. Registering a user with the application. One needs to create a CognitoUserPool object by providing a UserPoolId and a ClientId and signing up by using a username, password, attribute list, and validation data.
Use case 2. ユーザID(メールアドレス)認証
Use case 2. Confirming a registered, unauthenticated user using a confirmation code received via SMS.
Use case 4. ログイン(ユーザ認証)
Use case 4. Authenticating a user and establishing a user session with the Amazon Cognito Identity service.
その他、2つのAWS SDKが必要になるので全部で3つダウンロードしておきましょう。
ダウンロードできたら次から手順に従って作業開始です。
1.AWSコンソール Cognitoからユーザプールの作成
まずはAWSコンソールのCognitoのサービス画面からユーザープールの作成です。
基本的には画面の指示に従っていけば簡単にできます。
まずは、ユーザープールの管理をクリック。
ユーザープールを作成するをクリック。
好きなプール名を入力。
入力したらデフォルトを確認するをクリック。
デフォルト値で登録された設定内容の一覧が表示されます。
今回やりたいことを実現するために最低限、エイリアス属性、アプリクライアントの2つは変更する必要があります。
この後、画面が出てくればわかりますが、エイリアス属性は今回登録するユーザの属性設定、アプリクライアントはログイン画面を作成するプログラムを特定する設定になります。
では、まずエイリアス属性の選択をクリックし設定を行います。
今回はメールアドレスを使用するので、Eメールアドレスおよび電話番号を選択。
メールアドレスしか使用しないため他の属性はチェックせず、そのまま次のステップをクリック。
次に必須の設定となるアプリクライアントをクリック。
表示された画面でアプリクライアントの追加をクリック。
アプリクライアント名は好きな名前でOK。
今回、アプリクライアントの認証は実施しないためクライアントシークレットを生成のチェックを外します。
また、使用するSDKのライブラリはSRPプロトコルで認証しているためSRP (セキュアリモートパスワード) プロトコルベースの認証を有効にする (ALLOW_USER_SRP_AUTH)のチェックのみ残し後はチェックを外します。(「更新トークンベースの認証を有効にする」のチェックは外せません)
最後にアプリクライアントの作成をクリック。
プールの作成をクリックすると、ユーザープールが作成されます。
問題がなれけば作成された旨のメッセージと作成されたユーザープールの固有情報(プールIDとプールARN)が表示されます。
プールIDは次の手順のIDプール/実装するJavaScriptの中で指定する必要があるためメモしておきます。
加えて、アプリクライアントの情報も必要になるためアプリクライアントをクリック。
アプリクライアントIDが次の手順のIDプール/実装するJavaScriptの中で指定する必要があるためこちらもメモしておきます。
ここまででユーザープールの作成が完了です。
2.AWSコンソール CognitoからIDプールの作成
そのまま続けてAWSコンソールでIDプールを作成します。
ユーザープールに比べるとサクッとできます。
まずはIDプールの管理をクリック。
新しいIDプールの作成をクリック。
IDプール名は好きな名前でOK。
今回、認証プロバイダーには前の手順で作成したユーザープールを使用するため、Cognitoをクリック。
前の手順でメモしたユーザープールIDとアプリクライアントIDを入力します。
最後にプールの作成をクリック。
IDプールで使用するIAMが自動的に作成されるため、許可をクリック。
以上でIDプールの作成完了です。
今回はJavaScriptでクライアントを実装するため、表示された画面でJavaScriptを選択し表示された認証情報からIDプールのIDをメモしておきます。
3.画面実装 ユーザ登録画面(サインアップ画面)作成
ここからはHTML/JavaScriptで画面の作成を行います。
3画面を3つのHTML、3つのJavaScriptで作成します。
事前準備でダウンロードした3つのSDKを含め、JavaScriptはjsフォルダに格納するのため完成後のフォルダ構成は以下になります。
WORK_FOLDER\signup.html
WORK_FOLDER\confirm.html
WORK_FOLDER\auth.html
WORK_FOLDER\js
WORK_FOLDER\js\signup.js
WORK_FOLDER\js\confirm.js
WORK_FOLDER\js\auth.js
WORK_FOLDER\js\aws-sdk.min.js
WORK_FOLDER\js\aws-cognito-sdk.min.js
WORK_FOLDER\js\amazon-cognito-identity.min.js
(WORK_FOLDERはどこでも大丈夫です)
では、画面作成に移りましょう。
ユーザ登録画面はこんな感じの画面を作成します。
最初にHTMLです。以下をコピペしてテキストエディタで保存すればOKです。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"></meta>
<title>CognitoSignUp</title>
<script src="js/aws-cognito-sdk.min.js"></script>
<script src="js/amazon-cognito-identity.min.js"></script>
<script src="js/signup.js"></script>
</head>
<body>
<h1>CognitoSignUp</h1>
<span style="display: inline-block; width: 100px;">Email</span>
<input type="text" id="email" placeholder="Email Address">
<br/>
<span style="display: inline-block; width: 100px;">Password</span>
<input type="password" id="password" placeholder="Password">
<br/><br/>
<input type="button" value="CognitoSignUp" onclick="OnCognitoSignUp();">
</body>
</html>
次はJavaScriptです。
このJavaScriptサンプルは事前準備のところでリンクを貼り付けたamazon-cognito-identity-jsのUse case 1になります。
XXX部(ユーザープールIDとクライアントIDの2か所)、手順1.AWSコンソール Cognitoからユーザプールの作成でメモったIDに変えてください。
function OnCognitoSignUp() {
var poolData = {
UserPoolId: 'ap-northeast-1_XXXXXXXXX', // Your user pool id here
ClientId: 'XXXXXXXXXXXXXXXXXX', // Your client id here
};
var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
var username = document.getElementById("email").value;
var password = document.getElementById("password").value;
userPool.signUp(username, password, null, null, function(
err,
result
) {
if (err) {
alert(err.message || JSON.stringify(err));
return;
}
var cognitoUser = result.user;
console.log('user name is ' + cognitoUser.getUsername());
});
}
完成です!
では、signup.htmlにブラウザからアクセスしてみましょう。
うまく表示されたら有効なメールアドレスとパスワードを入力してCognitoSignUpボタンを押します。
成功していれば入力したメールアドレスに以下のメールが届くので認証コードを控えます。(この認証コードを次の画面で使います)
この状態になるとAWSコンソールからユーザープールにユーザが登録されたのが確認できます。
有効状態ではありますが、メールアドレスの認証が済んでいないのでUNCONFIRMED状態であることが確認できます。
確認できたら次の画面作成に進みましょう。
4.画面実装 ユーザID(メールアドレス)認証画面作成
引き続き、認証画面を作成します。完成後画面はこんな感じ。
まずはHTMLです。以下をコピペすればOKです。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"></meta>
<title>CognitoConfirmRegistration</title>
<script src="js/aws-cognito-sdk.min.js"></script>
<script src="js/amazon-cognito-identity.min.js"></script>
<script src="js/confirm.js"></script>
</head>
<body>
<h1>CognitoConfirmRegistration</h1>
<span style="display: inline-block; width: 100px;">Email</span>
<input type="text" id="email" placeholder="Email Address">
<br/>
<span style="display: inline-block; width: 100px;">ConfirmCode</span>
<input type="text" id="ConfirmCode" placeholder="Confirm Code">
<br/><br/>
<input type="button" value="CognitoConfirmRegistration" onclick="OnCognitoConfirmRegistration();">
</body>
</html>
JavaScriptです。
このサンプルはamazon-cognito-identity-jsのUse case 2になります。
最初の画面と同じでXXX部(ユーザープールIDとクライアントIDの2か所)、手順1.AWSコンソール Cognitoからユーザプールの作成でメモったIDに変えてください。
function OnCognitoConfirmRegistration() {
var poolData = {
UserPoolId: 'ap-northeast-1_XXXXXXXXX', // Your user pool id here
ClientId: 'XXXXXXXXXXXXXXXXXX', // Your client id here
};
var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
var username = document.getElementById("email").value;
var code = document.getElementById("ConfirmCode").value;
var userData = {
Username: username,
Pool: userPool,
};
var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
cognitoUser.confirmRegistration(code, true, function(err, result) {
if (err) {
alert(err.message || JSON.stringify(err));
return;
}
console.log('call result: ' + result);
});
}
完成です!!
confirm.htmlをブラウザで開き、メールアドレスとメールで届いた認証コードを入力、
CognitoConfirmRegistrationボタンを押します。
AWSコンソールでも状態を確認してみましょう。
CONFIRMED状態であること、Eメールアドレスが確認済みであることが確認できます。
確認できたら最後の画面作成に進みましょう。
5.画面実装 ログイン画面作成
HTMLです。前の手順のように以下をコピペすればOKですが、SDK(aws-sdk.min.js)が増えていることに注意しましょう。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"></meta>
<title>CognitoAuthenticateUser</title>
<script src="js/aws-sdk.min.js"></script>
<script src="js/aws-cognito-sdk.min.js"></script>
<script src="js/amazon-cognito-identity.min.js"></script>
<script src="js/auth.js"></script>
</head>
<body>
<h1>CognitoAuthenticateUser</h1>
<span style="display: inline-block; width: 100px;">Email</span>
<input type="text" id="email" placeholder="Email Address">
<br/>
<span style="display: inline-block; width: 100px;">Password</span>
<input type="password" id="password" placeholder="Password">
<br/><br/>
<input type="button" value="CognitoAuthenticateUser" onclick="OnCognitoAuthenticateUser();">
</body>
</html>
次にJavaScriptです。
このサンプルはamazon-cognito-identity-jsのUse case 4になります。
今ままでと同じでXXX部(ユーザープールIDとクライアントIDの2か所)がありますが、それに加えてファイル中ほどに、IDプールのIDとユーザープールID(似てますが、ユーザープールARNではないです)を設定する箇所があり、合計4か所の変更点があるので注意してください。
初登場のIDプールのIDは、手順2.AWSコンソール CognitoからIDプールの作成でメモったIDになります。
function OnCognitoAuthenticateUser() {
var username = document.getElementById("email").value;
var password = document.getElementById("password").value;
var authenticationData = {
Username: username,
Password: password,
};
var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(
authenticationData
);
var poolData = {
UserPoolId: 'ap-northeast-1_XXXXXXXXX', // Your user pool id here
ClientId: 'XXXXXXXXXXXXXXXXXX', // Your client id here
};
var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
var userData = {
Username: username,
Pool: userPool,
};
var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function(result) {
var idToken = result.getIdToken().getJwtToken(); // IDトークン
var accessToken = result.getAccessToken().getJwtToken(); // アクセストークン
var refreshToken = result.getRefreshToken().getToken(); // 更新トークン
console.log("idToken : " + idToken);
console.log("accessToken : " + accessToken);
console.log("refreshToken : " + refreshToken);
//POTENTIAL: Region needs to be set if not already set previously elsewhere.
AWS.config.region = 'ap-northeast-1';
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'ap-northeast-1:XXXXXXXXXXXXXXXXXX', // your identity pool id here
Logins: {
// Change the key below according to the specific region your user pool is in.
'cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_XXXXXXXXX': result
.getIdToken()
.getJwtToken(),
},
});
//refreshes credentials using AWS.CognitoIdentity.getCredentialsForIdentity()
AWS.config.credentials.refresh(error => {
if (error) {
console.error(error);
} else {
// Instantiate aws sdk service objects now that the credentials have been updated.
// example: var s3 = new AWS.S3();
console.log('Successfully logged!');
}
});
},
onFailure: function(err) {
alert(err.message || JSON.stringify(err));
},
});
}
完成です!!!
auth.htmlをブラウザで開き、メールアドレスとユーザー登録画面で入力したパスワードを入力、
CognitoAuthenticateUserボタンを押します。
こちらもAWSコンソールで確認します。ただし、今回の確認先はIDプールになります。
ログインするとアクティブなユーザーが1になっていることが確認できます。
今回は以上です!お疲れ様でした!!
まとめ
AWSコンソールの操作と簡単なHTML/JavaScriptでログイン画面を作ることができました。
予想より簡単だったのではないでしょうか?
認証情報が払い出されたので、ここからは認証情報を使って様々なAWSリソースにアクセスができるようになります。(認証情報に対しIAMで適切な権限付与は必要です)
これはCognitoのほんの一部の機能なのでまだまだできることはたくさんあるようです。
それも機をみてできる限り投稿していこうと思います。
ここまで読んで頂き、ありがとうございました!
資格取得に向けてAWSサービスを実際に利用してみるシリーズの投稿一覧
とりあえず30分でAWS利用料金の高額請求に備える~予算アラート設定・MFA・料金確認~
AWS ECSでDocker環境を試してみる
Amazon Cognitoを使ってシンプルなログイン画面を作ってみる(本記事)
AWS NATゲートウェイを使ってプライベートサブネットからインターネットにアクセスする
API GatewayをPrivateで作成してみる
AWSのAI(Rekognition/Polly/Transcribe/Comprehend/Translate/Textract)サービスを試してみる
AWS Lambda 同時実行数、エイリアス、環境変数とか実際の現場で使える機能を勉強してみる
AWS Lambda SAMとは?~AWS SAMを使ってPythonのLambdaプログラムを簡単に作成する~
Cloud9でAWS Amplifyの公式チュートリアルGetting startedをやってみる