amplify-js: user.sendCustomChallengeAnswer is not a function
This is a long article but organized pretty neat. Please read it and help me if you have any clue. It’s easy to reproduce using simple express application. (just separate Auth.signIn and Auth.sendCustomChallengeAnswer in different router)
Notice
Similar symptom found in old issue(#1896), but it seems to be happening in frontend, while I’m having it in backend.
=======
Which Category is your question related to? : Usage Question
What AWS Services are you utilizing? Cognito with Amplify Auth
Provide additional details e.g. code snippets
Current situation
-
I’m implementing Auth.signIn in express based Node.js REST API server. (Please note that this is backend application, not frontend such as react or angular).
-
So far, I’ve successfully implemented Auth.signUp, Auth.confirmSignUp and Auth.signIn.
-
For custom MFA (sending verification code to user’s email), I’m using CUSTOM_AUTH and my lambda functions bound to Cognito user pool are successfully triggered.
-
Currently implemented features(Auth.signUp, Auth.confirmSignUp and Auth.signIn) were implemented in separated endpoints(i.e., those Auth methods are called by different REST APIs), so as Auth.sendCustomChallengeAnswer that I’m having trouble with.
Problem
- As I separated Auth.signIn and Auth.sendCustomChallengeAnswer (due to the separation of endpoints, “/login” and “/verification/login”, respectively), user object returned by Auth.signIn is no longer available to pass to Auth.sendCustomChallengeAnswer.
Trial 1
- Here’s the
logincode snippet I’m using now:
// This is a method of Authentication Helper that "/login" endpoint calls.
// "/login" endpoint is express router which receives email and password from clients.
login(username, password, resolve, reject) {
Auth.signIn(username, password)
.then(user => {
if (user.challengeName === "CUSTOM_CHALLENGE") {
// Here, I tried to pass user object and save it in express-session.
// However, when I retrieve the user object from express-session in other api (/verification/login),
// the retrieved user object doesn't have sendCustomChallengeAnswer method.
resolve(user)
} else {
reject()
}
})
.catch(error => {
// Handling error...
})
}
- Here, passing user object and putting it in express-session doesn’t work as described in the comment above. This is the failed code snippet of
login verification:
// This is a method of Authentication Helper that "/verification/login" endpoint calls.
// argument "user" is retrieved from express-session and passed by "/verification/login" router.
verifyLoginTrial(user, code, resolve, reject) {
Auth.sendCustomChallengeAnswer(user, code)
.then(signedUser => {
console.log(signedUser)
resolve(signedUser)
})
.catch(error => {
// Handling error...
})
}
- Using this code, I got this error
user.sendCustomChallengeAnswer is not a function
Trial 2
-
Same code for
login -
This time, I’ve tried manually creating CognitoUser but it also didn’t work.
...
const CognitoUser = require("amazon-cognito-identity-js").CognitoUser
...
// Start of Authentication Helper
constructor() {
// Calling Amplify.configure()
...
this.userPool = new CognitoUserPool({
UserPoolId: poolData.UserPoolId,
ClientId: poolData.ClientId
})
}
...
// Here, instead of saving user object in express-session,
// I saved username and user.Session in express-session to manually create CognitoUser,
// which is directly imported from "amazon-cognito-identity-js" library
verifyLoginTrial(session, username, code, resolve, reject) {
// Manually create cognito user
const user = new CognitoUser({
Username: username,
Pool: this.userPool
})
user.authenticationFlowType = "CUSTOM_AUTH"
user.Session = session
// Send verification code
Auth.sendCustomChallengeAnswer(user, code)
.then(signedUser => {
console.log(signedUser)
resolve(signedUser)
})
.catch(error => {
// Handling error...
})
}
- Using this code, I got this error
AuthClass - Failed to get the signed in user No current user
Question
- How can I safely separate Auth.signIn and Auth.sendCustomChallengeAnswer?
- or more specifically, How can I safely pass user object returned by Auth.signIn to Auth.sendCustomChallengeAnswer in other API?
- if there’s no solution to question 2, then how can I call Auth.sendCustomChallengeAnswer with manually created CognitoUser without getting “No current user” error?
Thank you for reading this long question.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 4
- Comments: 17 (4 by maintainers)
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Our requirement was also the same and we managed to get the customAuth flow working by creating cognitoUserPool and cognitoUser instance from localStorage/sessionStorage before calling sendCustomChallengeAnswer.
Example: