reactjs – 使用Amplify持久保存AWS Cognito用户

我一直关注
Serverless Stack tutorial并且可以通过调用Auth.signIn(用户名,密码)获得积极响应

我们当前的工作流程是,用户需要重置密码,因为帐户将被分发.

.changePassword函数有3个参数; user,oldPassword,newPassword

我不能为我的生活找出它为用户寻找的东西.当我设置从.signIn()返回的对象时,我收到以下错误:

Local storage is missing an ID Token, Please authenticate

显然我不会将此流程用于生产,但我想弄清楚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 })
});

我确实从.signIn返回的对象中看到了存储属性中的ID令牌.澄清一下:我可能不应该把它放在链接中.我在实践中并没有真正做到这一点.当我从Signin保存响应并将其传递给changePassword时,我得到localstorage错误.我想知道是否有配置问题设置Amplify通常会将此信息放在localStorage中.

最佳答案
Auth.changePassword接收CognitoUser作为它的第一个参数,来自Auth.signIn的
should be returned.

这里的问题是你的承诺链接,并使用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() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall. Instead, use componentDidUpdate or a setState callback (setState(updater, callback)), either of which are guaranteed to fire after the update has been applied. If you need to set the state based on the previous state, read about the updater argument below.

解决此问题的最简单方法是在第一个.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 })
});

就个人而言,我认为在async / await中看起来会更好看:

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 })
}
点赞