AWS Cognito / React.js newPasswordRequired Challenge - PullRequest
0 голосов
/ 29 июня 2018

Я работаю над потоком входа в систему для моего веб-приложения, созданного в React, и использую AWS Cognito для управления пользователями. Я работаю над потоком входа в систему, и у меня есть случай использования, когда пользователь создается через консоль AWS, и пользователю предоставляется временный пароль. Когда пользователь впервые входит в мое приложение, AWS Cognito возвращает вызов newPasswordRequired, и пользователь вынужден сменить свой пароль.

Я использую amazon-cognito-identity-js API для аутентификации пользователя. Документы для этого можно найти здесь . У меня есть настройка функции обратного вызова newPasswordRequired, как указано в документации, но я изо всех сил пытаюсь найти лучший способ получить новый пароль от пользователя, используя React в функции newPasswordRequired. Сначала я использовал prompt() в функции для получения входных данных, но я бы хотел, чтобы приложение переместилось на новую страницу, где пользователь может ввести новый пароль, подтвердить новый пароль и войти в приложение. Эта новая страница должна вызывать cognitoUser.completeNewPasswordChallenge(), необходимый для обновления нового пароля. Пожалуйста помоги! Вот мой код ниже:

onFormSubmission = (username, password) => {
    const poolData = {
      UserPoolId : AWSConfig.cognito.USER_POOL_ID,
      ClientId : AWSConfig.cognito.APP_CLIENT_ID
    }
    const userPool = new CognitoUserPool(poolData);
    const userData = {
      Username: username,
      Pool: userPool
    }
    const authenticationData = {
        Username : username,
        Password : password
    }
    const authenticationDetails = new AuthenticationDetails(authenticationData);

    const cognitoUser = new CognitoUser(userData);

    cognitoUser.authenticateUser(authenticationDetails, {
      onSuccess: function (result) {
          console.log('access token + ' + 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*/
          console.log('idToken + ' + result.idToken.jwtToken);
      },
      onFailure: function(err) {
        console.log(err);
     },
     newPasswordRequired: function(userAttributes, requiredAttributes) {
          // User was signed up by an admin and must provide new
          // password and required attributes, if any, to complete
          // authentication.

          // userAttributes: object, which is the user's current profile. It will list all attributes that are associated with the user.
          // Required attributes according to schema, which don’t have any values yet, will have blank values.
          // requiredAttributes: list of attributes that must be set by the user along with new password to complete the sign-in.

*** THIS IS WHERE I WANT REACT TO RENDER A NEW PAGE TO GET THE NEW PASSWORD***

          // Get these details and call
          // newPassword: password that user has given
          // attributesData: object with key as attribute name and value that the user has given.
          cognitoUser.completeNewPasswordChallenge(pw, userAttributes, this);
      }
    });
  }

  render() {
    return (
      <div>
        <LoginScreenComponent isInvalidForm={this.state.isInvalidForm} onFormSubmission={this.onFormSubmission}/>
      </div>
    )
  }

1 Ответ

0 голосов
/ 29 июня 2018

У меня была точно такая же проблема! Вот мое решение:

Login.js Реагирующий контейнер может отображать два разных компонента. <NewPassswordForm /> - запросить новый пароль, <LoginForm /> - для обычного входа. В соответствии с флагом isFirstLogin вы решаете, какой из них отображать.

Поскольку у вас есть пользователь cognito в this.state.user, вы можете использовать его для вызова completeNewPasswordChallenge, чтобы завершить процесс входа в систему:

handleLogin = (username, password) => {
  const authDetails = new AuthenticationDetails({
    Username: username,
    Password: password,
  });
  const userData = {
    Username: username,
    Pool: getUserPool(),
    Storage: getStorage(),
  };
  const cognitoUser = new CognitoUser(userData);
  cognitoUser.authenticateUser(authDetails, {
    onSuccess: () => {
      // login
    }
    newPasswordRequired: userAttr => {
      this.setState({
        isFirstLogin: true,
        user: cognitoUser,
        userAttr: userAttr,
      });
    },
  });
};

changePassword = (newPassword) => {
  const cognitoUser = this.state.user;
  const userAttr = this.state.userAttr;
  cognitoUser.completeNewPasswordChallenge(newPassword, userAttr, {
    onSuccess: result => {
      // login
    }
  });
};

render() {
  return (
    <div>
      {this.state.isFirstLogin ? (
        <NewPassswordForm changePassword={this.changePassword} />
      ) : (
        <LoginForm handleLogin={this.handleLogin} />
      )}
    </div>
  );
}
...