所以我们使用await / async调用,但是aws-amplify提供的authenticateUser命令似乎使用了回调。我是一个python编码器,并且在很长一段时间内没有用节点编码,所以这可能是一个天真的问题!
我尝试将其转换为这样的承诺:
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目前失败)
答案 0 :(得分:5)
尝试使用现代Javascript构造实现对authenticateUser()
的调用对您有好处,但是您的方法存在一些问题。我真的很想知道完成的代码。
主要问题是Cognito authenticateUser()
需要三个回调,并且Promise只处理两个。如果您从不希望碰到该代码路径,则可以为newPasswordRequired
回调传递一个伪函数。另一种方法是对resolve
和onSuccess
回调都使用newPasswordRequired
函数。
第二个问题是您的authenticateUserAsync()
仅接受两个参数。您正在尝试向其传递一些其他回调。这些回调将被忽略。 那是它继续进行的原因,并且您收到未处理的promise异常。不必要的.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)
}
}
欢迎使用amazon-cognito-identity-js
的替代库,该库使用常见的ES6概念,例如async / await。
答案 1 :(得分:1)
这是使用asyc / 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()
关键字的函数内部
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)
}
}

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

答案 2 :(得分:0)
感谢这个问题(来自同一个python开发人员,对最新的节点模式有一定的了解)。基于此SO和其他一些OSS来源,在提供了合适的配置文件后,以下各项似乎可以工作(请参见下文)。旨在用作一个nodejs模块(解决方案在浏览器中会略有不同)。
/* jshint esversion: 8 */
/* jshint node: true */
// The amazon-cognito-identity-js package assumes fetch is available in a web browser. Since
// nodejs does not have fetch built-in it is emulated like this:
global.fetch = require("node-fetch");
const AmazonCognitoIdentity = require("amazon-cognito-identity-js");
function asyncCognitoAuthentication(cognitoConfig) {
const cognitoUserPool = new AmazonCognitoIdentity.CognitoUserPool({
UserPoolId: cognitoConfig.userPoolId,
ClientId: cognitoConfig.clientId,
});
const cognitoUser = new AmazonCognitoIdentity.CognitoUser({
Username: cognitoConfig.username,
Pool: cognitoUserPool,
});
const authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(
{
Username: cognitoConfig.username,
Password: cognitoConfig.password,
}
);
return new Promise(function (resolve, reject) {
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: resolve,
onFailure: reject,
newPasswordRequired: resolve,
});
});
}
const cognitoJWT = {
session: undefined,
jwtAccess: undefined,
jwtId: undefined,
jwtRefresh: undefined,
jwtPayloads: undefined,
};
module.exports.getCognitoJWT = async function (cognitoConfig) {
try {
const session = await asyncCognitoAuthentication(cognitoConfig);
cognitoJWT.session = session;
cognitoJWT.jwtAccess = session.getAccessToken().getJwtToken();
cognitoJWT.jwtId = session.getIdToken().getJwtToken();
cognitoJWT.jwtRefresh = session.getRefreshToken().getToken();
cognitoJWT.jwtPayloads = {
jwtAccess: session.getAccessToken().decodePayload(),
jwtId: session.getIdToken().decodePayload(),
};
return cognitoJWT;
} catch (error) {
console.log(error.message);
}
};
const process = require("process");
if (process.env.TEST_AUTH === "test") {
const config = require("config");
const cognitoConfig = config.get("cognito");
console.log(cognitoConfig);
Promise.resolve(module.exports.getCognitoJWT(cognitoConfig)).then(
(cognitoJWT) => {
console.log(cognitoJWT);
}
);
}
config
文件位于./config/default.json
中,具有以下结构(将实际值替换为{}
字段):
{
"logLevel": "info",
"cognito": {
"clientId": "{client-app-id}",
"userPoolId": "{aws-coginto-pool-id}",
"region": "{aws-region}",
"username": "{your-username}",
"password": "{your-password}"
}
}
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"
}
}