3

I am implementing Amazon Cognito User Pool authentication in my web app, and I ran in this problem - how to redirect user on newPasswordRequired callback to '/new-password' and await for inputs?

So in other words, my expected flow is User logs in with temporary password(here I fire cognitoUser.authenitcateUser), after that I redirect user to '/new-password' route and user sees the new password form(newPasswordRequired callback is triggered here).

Problem now is that SDK expects me to pass passwords in the newPassword callback but I don't know them yet(since the user will put it in new password form).

Code:

async login(values) {
const details = {
  Username: values.username,
  Password: values.password,
};

const authDetails = new AuthenticationDetails(details);
const userData = {
  Username: details.Username,
  Pool: poolData,
};

const cognitoUser = await new CognitoUser(userData);
await cognitoUser.authenticateUser(authDetails, {
  onSuccess: (result) => {
    console.log(userData);
    axios.defaults.headers.common.Authorization = result.getIdToken().getJwtToken();
    browserHistory.push('/entities');
  },
  onFailure: (error) => {
    console.log(userData);
    throw new Error(error);
  },
  newPasswordRequired: () => {
    browserHistory.push('/new-password');
    console.log(cognitoUser);
    console.log(cognitoUser.getAuthenticationFlowType(), 'YOU NEED TO CHANGE PASSWORD');
    const userData = {
      Username: cognitoUser.username,
      Pool: poolData,
    };
    cognitoUser.completeNewPasswordChallenge(
      values.newPassword,
      {},
      {
        onSuccess: (user) => {
          console.log('success', user);
        },
        onFailure: (error) => {
          console.log(error);
        },
      },
    );
  },
});

}

Another thing I tried was to create separate method which is responsible for calling cognitoUser.completeNewPasswordChallenge but then User Pool thinks that I am not authenticated.

My react component looks like this:

<form onSubmit={this.props.handleSubmit(AWSApi.login.bind(this))}></form>
  • Hey Gintaras, did you figure out a solution? – SamBrick Oct 31 '17 at 12:49
  • 1
    I did. in newPasswordRequired callback I redirect user to /new-password route. The route is displaying ForgotPasswordForm component, which onSubmit is calling another method, where I handle the logic of changing the password. The solution is dirty, but we decided to go with this one for now. – Gintaras Arštikaitis Nov 06 '17 at 12:11

1 Answers1

4

You need cognitoUser.Session for do cognitoUser.completeNewPasswordChallenge call after redirection. You can keep cognitoUser.Session in localstorage or set as a get parameter (yoururl?session=cognitoUser.Session) before redirection. Then in new page you can create new cognitoUser and set your old response session.

e.g.:

var userPool = new AmazonCognitoIdentity.CognitoUserPool(POOL_DATA);
var userData = {
    Username: username,
    Pool: userPool
};

var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
cognitoUser.Session = <your saved session>
cognitoUser.completeNewPasswordChallenge(....
joppiesaus
  • 5,471
  • 3
  • 26
  • 36