前回は、Amazon Cognitoを使ってサインアップ画面を実装しました。
サインアップしたはいいものの、アクティベーション処理をしなければ作成したユーザーは使うことができません。今回の記事では、前回の続きでアクティベーション処理とサインイン処理を実装したいと思います。今回は、HTMLやJavaScriptを用いたクライアントアプリの実装がメインになります。
前回のおさらい
簡単に前回のおさらいをします。サインアップすると、Amazon Cognitoのユーザープールにユーザーが作成されます。ただし、ステータスが「UNCONFIRMED」となっています。
そして、登録したEメールアドレスに検証コードが書かれたメールが送信されてきます。
この検証コードでアクティベーション処理を行い、完了後にはサインインができるようになります。
アクティベーション処理の実装
まずはアクティベーション処理を実装します。まずはアクティベーション画面の実装ですが、必要なJavaScriptライブラリは前回と同じです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Activation</title> <script src="js/anime.js"></script> <script src="js/aws-cognito/jsbn.js"></script> <script src="js/aws-cognito/jsbn2.js"></script> <script src="js/aws-cognito/sjcl.js"></script> <script src="js/aws-cognito/aws-sdk.min.js"></script> <script src="js/aws-cognito/aws-cognito-sdk.min.js"></script> <script src="js/aws-cognito/amazon-cognito-identity.min.js"></script> <script src="js/jquery-3.3.1.min.js"></script> <script src="js/activation.js"></script> </head> <body> <div id="activation"> <h1>Activation</h1> <div><span style="color: red;">All fields are required.</span></div> <form name="form-activation"> <span style="display: inline-block; width: 150px;">Email Address</span> <input type="text" id="email" placeholder="Email Address"> <br/> <span style="display: inline-block; width: 150px;">Activation Key</span> <input type="text" id="activationKey" placeholder="Activation Key"> <br/><br/> <input type="button" id="activationButton" value="Activation"> </form> </div> </body> </html> |
上記のHTMLをブラウザで開くと以下のような画面になります。
今回はEメールアドレスをユーザー名としてアカウント管理しているので、Eメールアドレスがユーザーを一意に特定できる情報となります。アクティベーションでは、Eメールアドレス(ユーザーを一意に特定できる情報)とアクティベーションキーをパラメータとして渡す必要があります。ここで言う「アクティベーションキー」は、先程のおさらいでも出てきた検証コードのことです。(「アクティベーション」という言葉に合わせて、言い方を変えています)
では、次にJavaScriptでアクティベーション処理を実装します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
// ユーザープールの設定 const poolData = { UserPoolId : [ユーザープールID], ClientId : [アプリクライアントID] }; const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData); /** * 画面読み込み時の処理 */ $(document).ready(function() { // Amazon Cognito 認証情報プロバイダーの初期化 AWSCognito.config.region = 'ap-northeast-1'; // リージョン AWSCognito.config.credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: [IDプールのID] }); // 「Activate」ボタン押下時 $("#activationButton").click(function(event) { activate(); }); }); /** * アクティベーション処理 */ var activate = function() { var email = $("#email").val(); var activationKey = $("#activationKey").val(); // 何か1つでも未入力の項目がある場合、処理を中断 if (!email | !activationKey) { return false; } var userData = { Username : email, Pool : userPool }; var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData); // アクティベーション処理 cognitoUser.confirmRegistration(activationKey, true, function(err, result){ if (err) { // アクティベーション失敗の場合、エラーメッセージを画面に表示 if (err.message != null) { $("div#message span").empty(); $("div#message span").append(err.message); } } else { // アクティベーション成功の場合、サインイン画面に遷移 } }); }; |
ユーザープールやプロバイダーの初期化はサインアップ機能を実装したときと同じでOKです。アクティベーションするには、CognitoUser#confirmRegistration関数を呼び出します。アクティベーションに失敗した場合は変数errとしてエラー情報オブジェクトが渡されてくるので、それをもとに成功/失敗を判断します。
それでは動作確認をしてみます。サインアップしてユーザーをつくると、冒頭でおさらいしたとおり、ステータスが「UNCONFIRMED」のユーザーが作成されます。
アクティベーション画面を開き、登録したメールアドレスに送信された検証コードでアクティベーションします。アクティベーション後、再度ユーザーのステータスを確認してみると…
ステータスが「CONFIRMED」に変わります!これでユーザー登録完了です。
サインイン処理の実装
それでは次に、サインイン処理を実装します。まずは画面です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Sign In</title> <script src="js/aws-cognito/jsbn.js"></script> <script src="js/aws-cognito/jsbn2.js"></script> <script src="js/aws-cognito/sjcl.js"></script> <script src="js/aws-cognito/aws-sdk.min.js"></script> <script src="js/aws-cognito/aws-cognito-sdk.min.js"></script> <script src="js/aws-cognito/amazon-cognito-identity.min.js"></script> <script src="js/jquery-3.3.1.min.js"></script> <script src="js/signin.js"></script> </head> <body> <div id="signin"> <h1>Sign In</h1> <div id="message"><span style="color: red;"></span></div> <form name="form-signin"> <span style="display: inline-block; width: 150px;">Email Address</span> <input type="text" id="email" placeholder="Email Address"> <br/> <span style="display: inline-block; width: 150px;">Password</span> <input type="password" id="password" placeholder="Password"> <br/><br/> <input type="button" id="signinButton" value="Sign In"> </form> </div> </body> </html> |
上記のHTMLをブラウザで開くと以下のような画面になります。
では、次にJavaScriptでサインイン処理を実装します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
// ユーザープールの設定 const poolData = { UserPoolId : [ユーザープールID], ClientId : [アプリクライアントID] }; const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData); /** * 画面読み込み時の処理 */ $(document).ready(function() { // Amazon Cognito 認証情報プロバイダーの初期化 AWSCognito.config.region = 'ap-northeast-1'; // リージョン AWSCognito.config.credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: [IDプールのID] }); // 「Sign In」ボタン押下時 $("#signinButton").click(function(event) { signIn(); }); }); /** * サインイン処理 */ var signIn = function() { var email = $('#email').val(); var password = $('#password').val(); // 何か1つでも未入力の項目がある場合、メッセージを表示して処理を中断 if (!email | !password) { $("#signin div#message span").empty(); $("#signin div#message span").append("All fields are required."); return false; } // 認証データの作成 var authenticationData = { Username: email, Password: password }; var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(authenticationData); var userData = { Username: email, 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); // サインイン成功の場合、次の画面へ遷移 }, onFailure: function(err) { // サインイン失敗の場合、エラーメッセージを画面に表示 console.log(err); $("div#message span").empty(); $("div#message span").append(err.message); } }); }; |
ユーザープールやプロバイダーの初期化はアクティベーション機能の実装と同じでOKです。画面で入力されたデータ(ここではEメールアドレスとパスワード)をもとに認証データ(authenticationData、40~43行目)を作成し、CognitoUser#authenticateUser関数を呼び出してユーザー認証します。認証成功時の処理はonSuccess関数(54~64行目)、認証失敗時の処理はonFailure関数(66~71行目)として定義します。
認証に成功すると、Amazon Cognitoから3つのトークンが返されます。それぞれIDトークン、アクセストークン、更新トークンと言い、上記ソース内の変数idToken(55行目)、accessToken(56行目)、refreshToken(57行目)がそれに当たります。それぞれのトークンについて、AWSのサイトでは以下のように説明されています。
ID トークンには、name、email、phone_number といった、認証されたユーザーの ID に関するクレームが含まれます。
アクセストークンは、認証されたリソースへのアクセスを付与します。
更新トークンには、新しい ID またはアクセストークンの取得に必要な情報が含まれます。
今回はこれらのトークンの詳細については触れませんが、例えばWeb APIの認証にIDトークンを使うなど、別のAWSサービスにアクセスする際の一時的な認証情報としてトークンを使うことができます。
それでは動作確認をしてみます。ブラウザでサインイン画面を開き、登録したユーザーでサインインします。Eメールアドレスとパスワードを入力し、「Sign In」ボタンをクリックします。
現段階では認証に成功しても画面遷移をしない(JavaScript処理を参照)ので画面上では何も起こりませんが、開発者ツールでコンソールに出力されているログを確認すると、前述した3つのトークンが発行されていることが確認できます。(トークンの値はマスクしているので少しわかりにくいかもしれませんが、赤く囲った3つです)
まとめ
前回と今回の記事で、サインアップでユーザー登録するところから、サインインで認証が成功するまでを実装してみました。Amazon Cognitoは、概念や仕組みを理解するのがやや難しいところもありますが、ユーザー登録の仕組みや認証基盤をスピーディに構築できるという点は大変便利だと思います。「AWSのサービスを使ったアプリを作ってみたい」、「やるならサーバーレスでやってみたい」と考えている方は、ぜひ認証基盤としてAmazon Cognitoを選択されてみてはいかがでしょうか。
執筆者プロフィール
- 社内の開発プロジェクトの技術支援や、新技術の検証に従事しています。主にアプリケーション開発系支援担当で、Java&サーバサイドが得意です。最近は、サーバーレスonAWSを推進しています。