Passwordless Auth with customChallenge (without Amplify)
See original GitHub issueWhich Category is your question related to? Cognito, CustomAuth flow
What AWS Services are you utilizing? Amazon Cognito Identity JS
Provide additional details e.g. code snippets
Hey, I am trying to implement passwordless login with cognito, where user receives a confirmation code via e-mail. The code is randomly generated in the createAuthChallenge lambda.
Following Use case 25 from https://github.com/aws-amplify/amplify-js/tree/master/packages/amazon-cognito-identity-js:
My app client sends a post request tomy backend /login
, which triggers the following function:
export const loginUser = (req, res) => {
const { email } = req.body;
const poolData = {
UserPoolId: MY_USER_POOL_ID,
ClientId: MY_USER_CLIENT_ID
};
const userPool = CognitoUserPool(poolData);
const userData = { Username: email, Pool: userPool };
const cognitoUser = new CognitoUser(userData);
const authenticationData = { Username: email };
const authenticationDetails = new AuthenticationDetails(authenticationData);
cognitoUser.setAuthenticationFlowType('CUSTOM_AUTH');
cognitoUser.initiateAuth(authenticationDetails, {
onSuccess: function(result) {
console.log('SUCESS', result);
},
onFailure: function(err) {
console.log('ERROR', err);
},
customChallenge: function(challengeParameters) {
let challengeResponse = challengeParameters.ANSWER;
cognitoUser.sendCustomChallengeAnswer(challengeResponse, this);
res.json(challengeParameters);
}
});
};
The problem is in customChallenge callback - this way I get successfully authenticated, onSuccess callback gets called and tokens are logged to the console. However, I do not want to already automatically sendCustomChallengeAnswer based on challangeParamaters. This should depend on the answer user fills in.
If I would send another post request to /login
with a code parameter in the request body, then I will always receive an error:
{
code: 'NotAuthorizedException',
name: 'NotAuthorizedException',
message: 'Incorrect username or password.'
}
This happens because the lambda initiates a new session with a new challange Answer code which is not equal to the one im trying to pass in the second POST request.
How can I implement custom auth flow using Amazon Cognito Identity sdk? I do not want to use Amplify.
I also tried this with initiateAuth & respondToAuthChallenge, but then I had an issue with the fact that respondToAuthChallenge() requires a Session parameter which is return by the initiateAuth() method (even though documentation says this is optional) - the Session token is only valid for 3 minutes, so unless there is a way to increase that limit it wont work for my use case:
// Gets triggered when a post request is made to /login:
export const loginUser = (req, res) => {
const {email} = req.body
const params = {
AuthFlow: 'CUSTOM_AUTH',
ClientId: MY_USER_CLIENT_ID,
AuthParameters: {
USERNAME: email
}
};
const identityProvider = new CognitoIdentityServiceProvider();
return identityProvider.initiateAuth(params, (err, data) => {
if (err) {
return next(err);
} else {
res.json(data);
}
});
}
// Gets triggered when a POST request is made to /authorize:
export const respondToChallenge = (req, res, next) => {
const { username, session, code } = req.body;
const params = {
ChallengeName: 'CUSTOM_CHALLENGE',
ClientId: MY_USER_CLIENT_ID,
ChallengeResponses: { USERNAME: username, ANSWER: code },
Session: session
};
const identityProvider = new CognitoIdentityServiceProvider();
identityProvider.respondToAuthChallenge(params, (err, data) => {
if (err) {
return next(err);
} else {
res.json(
data.AuthenticationResult
);
}
});
};
Any help or suggestions are very much appreciated, thank you!
Issue Analytics
- State:
- Created 4 years ago
- Comments:12 (3 by maintainers)
Top GitHub Comments
@KristineTrona There is not currently a way to increase the expiration time. I will mark this as a feature request and bring it to the Service Team’s attention
can you expand on this hack a bit more, please?
“You need to cancel the login flow” - How do I cancel the login flow? "Save some hash in the backend (DynamoDB or something like that) "- Is this hash the hash for the code itself or identified for the user login attempt?
Would be great if you could share a bit more information about it.
@rothalex
@devTechi