Persist AWS Cognito Пользователь с Amplify - PullRequest
0 голосов
/ 27 ноября 2018

Я следую учебному пособию без сервера и могу получить положительный ответ, позвонив Auth.signIn(username, passsword)

. Текущий рабочий процесс, который мы имеем, заключается в том, что пользователю потребуется сбросить свой парольпо мере выдачи счетов.

Функция .changePassword принимает 3 аргумента;user, oldPassword, newPassword

Я не могу на всю жизнь понять, что он ищет для пользователя.Когда я устанавливаю объект, возвращенный из .signIn(), я получаю следующую ошибку:

В локальном хранилище отсутствует идентификатор токена. Пожалуйста, аутентифицируйтесь

Очевидно, я бы не использовалэтот поток для производства, но я пытаюсь выяснить, что ищет Auth.

Auth.signIn(this.state.emailAddress, this.state.password)
  .then(user => {
    this.setState({ isLoading: false, user });
  }).then(async () => {
    Auth.changePassword(this.state.user, 'P@ssw0rd!', 'NewP@ssw0rd!');
  }).catch(err => {
    this.setState({ isLoading: false, errorMessage: err.message })
});

Я вижу токен ID в свойстве Storage для объекта, возвращенного из .signIn.Для пояснения: я, вероятно, не должен был помещать это в цепь.Я на самом деле не делаю выше на практике.Когда я сохраняю ответ от Signin и передаю его changePassword, я получаю ошибку localalstorage.Мне интересно, есть ли проблема с настройкой конфигурации Amplify, которая обычно помещает эту информацию в localStorage.

1 Ответ

0 голосов
/ 01 декабря 2018

Auth.changePassword принимает CognitoUser в качестве первого аргумента, то, что должно быть возвращено из Auth.signIn.

Проблема здесь в том, чтоцепочка вашего обещания и использование this.setState() и чтение его до того, как оно действительно будет установлено:

Auth.signIn(this.state.emailAddress, this.state.password)
  .then(user => {
    // Triggers a setstate here:
    this.setState({ isLoading: false, user });
  }).then(async () => {
    // this.state.user is not defined at this point
    Auth.changePassword(this.state.user, 'P@ssw0rd!', 'NewP@ssw0rd!');
  }).catch(err => {
    this.setState({ isLoading: false, errorMessage: err.message })
});

Из React docs :

setState() не всегда сразу обновляет компонент.Это может пакетировать или отложить обновление до позже.Это делает чтение this.state сразу после вызова setState() потенциальной ошибкой.Вместо этого используйте componentDidUpdate или setState обратный вызов (setState(updater, callback)), который гарантированно сработает после применения обновления.Если вам нужно установить состояние на основе предыдущего состояния, прочтите об аргументе средства обновления ниже.

Самый простой способ исправить это - вернуть пользователя в первом .then обратном вызове, чтобыпередайте его второму:

Auth.signIn(this.state.emailAddress, this.state.password)
  .then(user => {
    // Triggers a setstate here:
    this.setState({ isLoading: false, user });
    return user;
  }).then((user) => {
    // this.state.user is not defined at this point
    Auth.changePassword(user, 'P@ssw0rd!', 'NewP@ssw0rd!');
  }).catch(err => {
    this.setState({ isLoading: false, errorMessage: err.message })
});

Лично я думаю, что в асинхронном режиме / ожидании это будет выглядеть намного лучше:

try {
    const user = await Auth.signIn(this.state.emailAddress, this.state.password);

    this.setState({ isLoading: false, user });

    await Auth.changePassword(user, 'P@ssw0rd!', 'NewP@ssw0rd!');
} catch (err) {
    this.setState({ isLoading: false, errorMessage: err.message })
}
...