https://dev.classmethod.jp/cloud/aws/login-form-by-using-aws-sdk-for-javascript/ はとても参考になったが、記事が使っているAWSのJavascript向けSDKが古かった。そこで公式の https://github.com/aws/aws-amplify/blob/master/packages/amazon-cognito-identity-js/README.md を参照しつつ v1.32.0 時点の仕様で動くようにして試してみた。
amazon-cognito-identity.min.js は 2018/3/9 現在最新の下記リビジョン。
https://github.com/aws/aws-amplify/blob/62f7f2e365a1b4b99e9ebdf55e30199121afa19b/packages/amazon-cognito-identity-js/dist/amazon-cognito-identity.min.js
なお css は https://codepen.io/Lewitje/pen/BNNJjo のものを使わせてもらったが、無くても Cognito の確認には支障ない。
js/common.js
下記のID類を Cognito の管理画面か Admin API で作成して揃えておく。
var AWS_REGION = 'ap-northeast-1'; var COGNITO_IDENTITY_POOL_ID = 'ap-northeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'; var COGNITO_USER_POOL_ID = 'ap-northeast-1_XXXXXXXXX'; var COGNITO_CLIENT_ID = 'xxxxxxxxxxxxxxxxxxxxxxxxxx'; var COGNITO_IDP = 'cognito-idp.' + AWS_REGION + '.amazonaws.com/' + COGNITO_USER_POOL_ID;
login.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Login</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <div class="wrapper"> <div class="container"> <h1 class="msg">Welcome</h1> <form class="form"> <input type="text" placeholder="Username" id="name"> <input type="password" placeholder="Password" id="password"> <button type="submit" id="login-button">Login</button> </form> </div> </div> <script src="js/amazon-cognito-identity.min.js"></script> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.5.2.min.js"></script> <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script> <script src="js/common.js"></script> <script src="js/login.js"></script> </body> </html>
js/login.js
newPasswordRequired に管理コンソール上でアカウント作成した場合の強制パスワード変更の実装を簡易にしてある。
// js client では ClientID に client secret が生成されていると動作しない AWS.config.region = AWS_REGION; AWS.config.credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: COGNITO_IDENTITY_POOL_ID, }); var CognitoUserPool = AmazonCognitoIdentity.CognitoUserPool; var poolData = { UserPoolId: COGNITO_USER_POOL_ID, ClientId: COGNITO_CLIENT_ID, Paranoia : 7 }; var userPool; var cognitoUser; $("#login-button").click(function(event){ event.preventDefault(); var authenticationData = { Username : $('#name').val(), Password : $('#password').val() }; var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(authenticationData); var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData); var userData = { Username : $('#name').val(), Pool : userPool }; cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData); cognitoUser.authenticateUser(authenticationDetails, { onSuccess: function (authresult) { var url = "mypage.html"; $('form').fadeOut(700, function(){ $(location).attr("href", url); }); $('.wrapper').addClass('form-success'); }, onFailure: function(err) { console.log('onFailure'); alert('msg='+ err.message); }, mfaRequired: function(codeDeliveryDetails) { // MFA is required to complete user authentication. // Get the code from user and call cognitoUser.sendMFACode(mfaCode, this) }, newPasswordRequired: function(userAttributes, requiredAttributes) { // User was signed up by an admin and must provide new // password and required attributes, if any, to complete // authentication. console.log('newPasswordRequired'); console.log(userAttributes, requiredAttributes); // the api doesn't accept this field back delete userAttributes.email_verified; // これらの必要性はUserPoolの設定による userAttributes.address='a'; userAttributes.given_name='b'; userAttributes.family_name='c'; userAttributes.middle_name='d'; // phone number はこの形式の必要がある userAttributes.phone_number='+818012345678'; console.log(userAttributes); // Get these details and call cognitoUser.completeNewPasswordChallenge('0101abab', userAttributes, this); } }); });
mypage.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>mypage</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <div class="wrapper"> <div class="container"> <div class="mypage"> <h1>mypage</h1> <div id="username">Username: XXXXX</div> <div id="email">EMail: XXXXX</div> </div> </div> </div> <script src="js/amazon-cognito-identity.min.js"></script> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.5.2.min.js"></script> <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script> <script src="js/common.js"></script> <script src="js/mypage.js"></script> </body> </html>
js/mypage.js
// js client では ClientID に client secret が生成されていると動作しない AWS.config.region = AWS_REGION; AWS.config.credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: COGNITO_IDENTITY_POOL_ID, }); var CognitoUserPool = AmazonCognitoIdentity.CognitoUserPool; var poolData = { UserPoolId: COGNITO_USER_POOL_ID, ClientId: COGNITO_CLIENT_ID, Paranoia : 7 }; var userPool; var cognitoUser; var authenticationData = { Username : $('#name').val(), Password : $('#password').val() }; var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(authenticationData); var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData); var userData = { Username : $('#name').val(), Pool : userPool }; // これがポイント cognitoUser = userPool.getCurrentUser(); if (cognitoUser != null) { cognitoUser.getSession(function(err, sessresult) { if (sessresult) { console.log('You are now logged in.'); cognitoUser.getUserAttributes(function(err, attrresult) { if (err) { alert(err); return; } $("#username").html("Username: " + cognitoUser.username); for (i = 0; i < attrresult.length; i++) { if (attrresult[i].getName()=="email"){ $("#email").html("EMail: " + attrresult[i].getValue()); } } // Add the User's Id Token to the Cognito credentials login map. AWS.config.credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: COGNITO_IDENTITY_POOL_ID, Logins: { COGNITO_IDP: sessresult.getIdToken().getJwtToken() } }); }); } else { var url = "login.html"; $(location).attr("href", url); } }); } else { var url = "login.html"; $(location).attr("href", url); }