Reactjs 如何等待aws cognito authenticateUser调用(似乎是回调)

Reactjs 如何等待aws cognito authenticateUser调用(似乎是回调),reactjs,callback,async-await,aws-amplify,cognito,Reactjs,Callback,Async Await,Aws Amplify,Cognito,所以我们使用wait/async调用,但是aws amplify提供的authenticateUser命令似乎使用回调。我是一名python程序员,很久没有使用node进行编码了,所以这可能是一个幼稚的问题 我试着把它变成这样的承诺: function authenticateUserAsync(user, authDetails) { return new Promise(function(resolve, reject, challenge) { user.aut

所以我们使用wait/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; 
        });
}
后来

 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';
    } 
  );

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

这里是使用asyc/await的正确方法,您不能单独使用
await
关键字,它应该在函数签名中包含
async
关键字的函数中

const fetchData=async()=>{
试一试{
const res=等待取数('https://jsonplaceholder.typicode.com/posts/1')
const data=await res.json()
console.log(数据)
}捕捉(错误){
console.log('error from fetch:',err)
}
}

fetchData()
非常适合尝试使用现代Javascript构造实现对
authenticateUser()
的调用,但是您的方法存在一些问题。我真的很想看看完成的代码

主要问题是Cognito
authenticateUser()
需要三次回调,承诺只处理两次。如果您从未想过要访问该代码路径,则可以为
newPasswordRequired
回调传递一个伪函数。另一种方法是对
onSuccess
newPasswordRequired
回调使用
resolve
函数

第二个问题是,
authenticateUserAsync()
只接受两个参数。您正在尝试向它传递一些额外的回调。这些回调被忽略。这就是为什么它会马上流过去,而您会得到一个未处理的承诺例外。不必要的
.then()
也没有帮助

我的实现结果如下:

函数asyncAuthenticateUser(cognitoUser,cognitoAuthenticationDetails){
返回新承诺(功能(解决、拒绝){
cognitoUser.authenticateUser(cognitoAuthenticationDetails{
成功:决心,
失败:拒绝,
newPasswordRequired:解析
})
})
}
异步登录({commit},authData){
让cognitoUserPool=newCognitoUserPool(config.poolDetails)
让cognitoAuthenticationDetails=新的AuthenticationDetails(authData);
让userData={Username:authData.Username,Pool:cognitoUserPool}
让cognitoUser=新cognitoUser(userData)
试一试{
让结果=
等待asyncAuthenticateUser(cognitoUser,cognitoAuthenticationDetails)
if(结果中的('idToken')){
log('我们有一个标记:'+JSON.stringify(p));
}
否则{
console.log('我们需要一个新密码')
删除结果。电子邮件\u已验证//质询呼叫未接受
删除结果。电话号码已验证//也不接受
//从用户处获取新密码,然后调用
//cognitoUser.completeNewPasswordChallenge()
}
捕获(错误){
//可能是输入错误的密码
console.log(错误消息)
}
}
感谢您提出这个问题(来自一位对最近的节点模式有所了解的python开发人员)。基于此以及其他一些OSS源代码,如果提供了合适的配置文件(请参见下文),以下内容似乎可以工作。这是一个nodejs模块(解决方案在浏览器中略有不同)

/*jshint esversion:8*/
/*jshint节点:true*/
//amazon cognito identity js包假设fetch在web浏览器中可用
//nodejs没有内置的fetch,它是这样模拟的:
global.fetch=require(“节点获取”);
const AmazonCognitoIdentity=require(“amazoncognito identity js”);
函数asyncCognitoAuthentication(cognitoConfig){
const cognitoUserPool=new AmazonCognitoIdentity.cognitoUserPool({
UserPoolId:cognitoConfig.UserPoolId,
ClientId:cognitoConfig.ClientId,
});
const cognitoUser=new AmazonCognitoIdentity.cognitoUser({
用户名:cognitoConfig.Username,
池:cognitoUserPool,
});
const authenticationDetails=新的AmazonCongnitoIdentity.authenticationDetails(
{
用户名:cognitoConfig.Username,
密码:cognitoConfig.Password,
}
);
返回新承诺(功能(解决、拒绝){
cognitoUser.authenticateUser(authenticationDetails{
成功:决心,
失败:拒绝,
newPasswordRequired:解析,
});
});
}
const cognitoJWT={
会话:未定义,
jwtAccess:未定义,
jwtId:未定义,
jwtRefresh:未定义,
jwtPayloads:未定义,
};
module.exports.getCognitoJWT=异步函数(cognitoConfig){
试一试{
const session=等待异步CognitoAuthentication(cognitoConfig);
cognitoJWT.session=会话;
cognitoJWT.jwtAccess=session.getAccessToken().getJwtToken();
cognitoJWT.jwtId=session.getIdToken().getJwtToken();
cognitoJWT.jwtRefresh=session.getRefreshToken().getToken();
cognitoJWT.jwt有效载荷={
jwtAccess:session.getAccessToken().decodePayload(),
jwtId:session.getIdToken().decodePayload(),
};
返回cognitoJWT;
}捕获(错误){
console.log(错误消息);
}
};
常数过程=要求(“过程”);
if(process.env.TEST_AUTH==“TEST”){
const config=require(“配置”);
const cognitoConfig=config.get(“cognito”);
log(cognitoConfig);
resolve(module.exports.getCognitoJWT(cognitoConfig))。然后(
(cognitoJWT)=>{
console.log(cognitoJWT);
}
);
}
config
文件位于
/config/default.json
中,结构如下(将实际值替换为
{}
字段):

package.json
类似于:

{
  "scripts": {
    "test-cognito-auth": "TEST_AUTH=test node ./cognito_auth.js"
  },
  "license": "Apache 2.0",
  "dependencies": {
    "amazon-cognito-identity-js": "^4.3.0",
    "aws-sdk": "^2.686.0",
    "config": "^3.3.1",
    "node-fetch": "^2.6.0",
    "process": "^0.11.10",
  },
  "devDependencies": {
    "prettier": "^2.0.5"
  }
}

是的,我忘了提到我的代码片段在一个异步函数中,一个更大的onSubmit处理程序中-但我现在正在尝试你的解决方案,在里面是的,非常感谢
{
  "scripts": {
    "test-cognito-auth": "TEST_AUTH=test node ./cognito_auth.js"
  },
  "license": "Apache 2.0",
  "dependencies": {
    "amazon-cognito-identity-js": "^4.3.0",
    "aws-sdk": "^2.686.0",
    "config": "^3.3.1",
    "node-fetch": "^2.6.0",
    "process": "^0.11.10",
  },
  "devDependencies": {
    "prettier": "^2.0.5"
  }
}