如何等待 aws cognito authenticateUser 调用(这似乎是一个回调)

Gol*_*lez 4 callback async-await reactjs aws-amplify cognito

所以我们使用了 await/async 调用,但是 aws-amplify 提供的 authenticateUser 命令似乎使用了回调。我是一名 python 编码员,已经有一段时间没有使用 node 进行编码了,所以这可能是一个天真的问题!

我尝试将其转换为这样的承诺:

function authenticateUserAsync(user, authDetails) {
    return new Promise(function(resolve, reject, challenge) {
          user.authenticateUser(authDetails, { 
                          onSuccess: resolve,
                          onFailure: reject, 
                          newPasswordRequired: challenge });

    }).then(
        function(result) { 
           return result; 
        });
}
Run Code Online (Sandbox Code Playgroud)

然后

 idToken = await authenticateUserAsync(user, authDetails,
    function(result) {
        console.log("Token: ");
        console.log(result.idToken);
        return result.idToken;
    },
    function(err) {
        console.log(err);
        this.setState({idToken: ''});
        if (err.code == 'NotAuthorizedException') {
                return 'not_authorized';
        } else {
                return 'unknown_error';
        }

    },
    function(userAttrs, reqAttrs) {
        return 'challenge';
    } 
  );
Run Code Online (Sandbox Code Playgroud)

但是,无论我如何调整它,代码都会继续运行,然后我得到一个未处理的承诺拒绝(在我的测试中,此时身份验证失败)

Mar*_*ark 7

很高兴您尝试authenticateUser()使用现代 Javascript 构造实现对 的调用,但是您的方法存在几个问题。我真的很想看到完成的代码。

主要问题是 CognitoauthenticateUser()需要三个回调,而 Promise 只处理两个。newPasswordRequired如果您从不期望命中该代码路径,则可以为回调传递一个虚拟函数。另一种方法是对回调和回调resolve都使用该函数。onSuccessnewPasswordRequired

第二个问题是你authenticateUserAsync()只需要两个参数。您正在尝试向它传递一些额外的回调。这些回调被忽略。就是为什么它直接流过并且你得到一个未处理的承诺异常。不必要的.then()也无济于事。

我的实现最终是这样的:

function asyncAuthenticateUser(cognitoUser, cognitoAuthenticationDetails) {
  return new Promise(function(resolve, reject) {
    cognitoUser.authenticateUser(cognitoAuthenticationDetails, {
      onSuccess: resolve,
      onFailure: reject,
      newPasswordRequired: resolve
    })
  })
}

async signIn({ commit }, authData) {
  let cognitoUserPool = new CognitoUserPool(config.poolDetails)
  let cognitoAuthenticationDetails = new AuthenticationDetails(authData);
  let userData = { Username: authData.Username, Pool: cognitoUserPool }
  let cognitoUser = new CognitoUser(userData)

  try {
    let result =
      await asyncAuthenticateUser(cognitoUser, cognitoAuthenticationDetails)

    if ('idToken' in result) {
      console.log('We have a token:  ' + JSON.stringify(p));
    }
    else {
      console.log('We need a new password.')
      delete result.email_verified // Not accepted by the challenge call
      delete result.phone_number_verified // Also not accepted

      // Get a new password from the user then call
      // cognitoUser.completeNewPasswordChallenge()
    }
    catch (error) {
      // Probably a mis-typed password
      console.log(error.message)
    }
}
Run Code Online (Sandbox Code Playgroud)

amazon-cognito-identity-js欢迎使用通用 ES6 概念(如 async/await)的替代库。


sra*_*nji 1

这是使用 asyc/await 的正确方法,不能单独使用关键字,它应该在函数签名中await带有关键字的函数内部async

const fetchData = async () => {
  try{
  const res = await fetch('https://jsonplaceholder.typicode.com/posts/1')
  const data = await res.json()
   console.log(data)
  }catch(err){
     console.log('error from fetch : ',err)
  }
}

fetchData()
Run Code Online (Sandbox Code Playgroud)

我认为在你的例子中你可以做这样的事情

const getIdToken = async () => {
  try{
  idToken = await authenticateUserAsync(user, authDetails,
    function(result) {
        console.log("Token: ");
        console.log(result.idToken);
        return result.idToken;
    },
    function(err) {
        console.log(err);
        this.setState({idToken: ''});
        if (err.code == 'NotAuthorizedException') {
                return 'not_authorized';
        } else {
                return 'unknown_error';
        }

    },
    function(userAttrs, reqAttrs) {
        return 'challenge';
    } 
  );
  return idToken;
  }catch(err){
     console.log('error from fetch : ',err)
  }
}
Run Code Online (Sandbox Code Playgroud)