Reputation: 952
I am building a proof of concept web app and would like to use an AWS Cognito User Pool as my user authentication mechanism. I have configured a user pool and a client app. I have used the hosted UI to sign up a test user. Now I need to authenticate that user from the browser.
I have found two examples in AWS documentation (here and here) showing how to authenticate users against Cognito User Pools with browser-based javascript. I can't get either one to work for me.
Here's my minimum-code demonstration HTML (two textboxes and a button):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test Page</title>
</head>
<body>
<input id="username" type="text" value="myUser"></input> <br>
<input id="password" type="password" value="myPa55w0rd!"></input> <br>
<button onclick="login()">Log In!</button>
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.726.0.js"></script>
<script src="js/myscript.js"></script>
</body>
</html>
Here's my myscript.js (version 1, from https://aws.amazon.com/blogs/mobile/accessing-your-user-pools-using-the-amazon-cognito-identity-sdk-for-javascript/):
function login() {
AWS.config.region = "us-west-2";
var poolData = {
UserPoolId : 'us-west-2_redacted',
ClientId : 'abcdefghijklmnopqrstuvwxyz'
};
var userPool = new AWS.CognitoIdentityServiceProvider.CognitoUserPool(poolData); <--Error here
var authenticationData = {
Username : document.getElementById("username").value,
Password : document.getElementById("password").value
};
var authenticationDetails = new AWSCognito.CognitoIdentityServiceProvider.authenticationDetails(authenticationData);
var userData = {
Username : document.getElementById("username").value,
Pool: userPool
};
var cognitoUser = new AmazonCognito.CognitoIdentityServiceProvider.cognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
var accessToken = result.getAccessToken().getJwtToken();
/* Use the idToken for Logins Map when Federating User Pools with identity pools or when passing through an Authorization Header to an API Gateway Authorizer */
var idToken = result.idToken.jwtToken;
alert("Authentication successful!");
},
onFailure: function(err) {
alert(err);
},
});
}
When I run this code, I get Uncaught TypeError: AWS.CognitoIdentityServiceProvider.CognitoUserPool is not a constructor
in the line var userPool = new AWS.CognitoIdentityServiceProvider.CognitoUserPool(poolData);
. Sure enough, I don't see 'CognitoUserPool' anywhere in the aws-sdk-2.726.0.js file.
Here is my second attempt, using the code example at https://docs.aws.amazon.com/cognito/latest/developerguide/authentication.html:
function login() {
var authenticationData = {
Username : document.getElementById("username").value,
Password : document.getElementById("password").value
}
var authenticationDetails = new AmazonCognitoIdentity.authenticationDetails(authenticationData); <-- Error here
var poolData = {
UserPoolId : 'us-west-2_redacted',
ClientId : 'abcdefghijklmnopqrstuvwxyz'
};
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 accessToken = result.getAccessToken().getJwtToken();
/* Use the idToken for Logins Map when Federating User Pools with identity pools or when passing through an Authorization Header to an API Gateway Authorizer */
var idToken = result.idToken.jwtToken;
},
onFailure: function(err) {
alert(err);
},
});
}
When I run this code, I get Uncaught ReferenceError: AmazonCognitoIdentity is not defined
. Sure enough, the text 'AmazonCognitoIdentity' does not appear in the aws.sdk-2.726.0.js file.
I've been chasing my tail on this and so far haven't found a solution. I would very much like to avoid moving to the Amplify framework. That carries with it the cost of a steep learning curve for a new framework that I'd rather avoid, at least for now. In addition, I'm barely a JS programmer, and am certainly not a node programmer, so I'd have to climb the hill of learning node.js as well to make the move to Amplify.
Is it possible to authenticate a user with simple client-side Javascript, without using Amplify? If so, I'd greatly appreciate a full working example (or someone pointing out what I'm doing wrong.)
Upvotes: 2
Views: 4393
Reputation: 952
For anyone who's coming after me with this problem, I found a solution. Whether it's the right solution or not, I don't know. Best of luck to y'all:
function login() {
AWS.config.update({region : "us-west-2"});
const payload = {
AuthFlow: "USER_PASSWORD_AUTH",
ClientId: "abcdefghijklmnopqrstuvwxyz",
AuthParameters : {
USERNAME: document.getElementById('username').value,
PASSWORD: document.getElementById('password').value
}
}
var cognito = new AWS.CognitoIdentityServiceProvider();
cognito.initiateAuth(payload, function(err,data) {
if (err) {
alert("Error: " + err);
}
else {
alert("Success!");
}
})
}
Upvotes: 2