首页 > 解决方案 > 使用 Amplify 持久化 AWS Cognito 用户

问题描述

我一直在关注无服务器堆栈教程,并且可以通过调用获得积极响应Auth.signIn(username, passsword)

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

.changePassword函数有 3 个参数;用户、旧密码、新密码

我一生都无法弄清楚它在为用户寻找什么。当我设置从返回的对象时,.signIn()出现以下错误:

本地存储缺少 ID 令牌,请进行身份验证

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

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

标签: reactjsamazon-web-servicesamazon-cognitoaws-amplifyamplifyjs

解决方案


Auth.changePassword接受 aCognitoUser作为它的第一个参数,应该从 . 返回的东西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 文档

setState()并不总是立即更新组件。它可能会批量更新或将更新推迟到以后。这使得在调用setState()潜在陷阱后立即阅读 this.state。取而代之的是使用componentDidUpdatesetState回调 ( setState(updater, callback)),它们都保证在应用更新后触发。如果您需要根据之前的状态设置状态,请阅读下面的 updater 参数。

解决此问题的最简单方法是在第一个回调中返回用户,然后.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 })
}

推荐阅读