我正在为一个学校项目编写一个带有NodeJS和Express的API,我正在努力解决以下问题:
函数getAuthUserId解码JWT令牌并从mongoDB服务器中的用户获取Id。
我在REST调用“/ user / authTest”中调用此函数。但是当我调用它时,服务器会在数据库返回Id之前响应,并且变量UId未定义。如您所见,ID实际上已找到。关于如何解决这个问题的任何想法?
API调用代码:
apiRoutes.post('/user/authTestID', function(req, res) {
var UId = getAuthUserId(req, res);
console.log(UId);
if (UId) {
res.sendStatus(200);
}else{
res.sendStatus(400);
}
});
功能:
function getAuthUserId(req, res) {
var user = new User();
var token = user.getToken(req.headers);
if (token) {
var decoded = jwt.decode(token, config.secret);
User.findOne({
name: decoded.name
}, function(err, user) {
if (err) throw err;
if (!user) {
res.status(403).send({success: false, msg: 'Authentication failed. User not found.'});
return false
} else {
console.log('Auth for ' + user.name + ' ' + user._id);
return user._id
}
});
} else {
res.status(403).send({success: false, msg: 'No token provided.'});
return '';
}
}
终端的输出:
[nodemon] restarting due to changes...
[nodemon] starting `node server.js`
Connected to MongoDB
undefined
::ffff:192.168.0.111 - POST /user/authTestID HTTP/1.1 400 11 - 175.006 ms
Auth for test 58f8954c3602b80552b6f1fb
提前致谢!
答案 0 :(得分:2)
你需要做出承诺,就像这样。
apiRoutes.post('/user/authTestID', function(req, res) {
getAuthUserId(req, res).then(function (UId) => {
console.log(UId);
if (UId) {
res.sendStatus(200);
}else{
res.sendStatus(400);
}
});
}, function(err) {
console.log(err.msg)
res.status(err.status).send(err.msg);
});
function getAuthUserId(req, res) {
return new Promise(function(resolve, reject){
var user = new User();
var token = user.getToken(req.headers);
if (token) {
var decoded = jwt.decode(token, config.secret);
User.findOne({
name: decoded.name
}, function(err, user) {
if (err) throw err;
if (!user) {
reject({status: 403, msg: 'Authentication failed. User not found.'});
} else {
console.log('Auth for ' + user.name + ' ' + user._id);
resolve(user._id)
}
});
} else {
reject({status: 403, msg: 'No token provided.'});
}
})
}
答案 1 :(得分:2)
getAuthUserId
获取 CALLBACK !!! 中的值。你不能指望它从它返回值。快速的事情你可以做如下的事情。
apiRoutes.post('/user/authTestID', function (req, res) {
var user = new User();
var token = user.getToken(req.headers);
if (token) {
var decoded = jwt.decode(token, config.secret);
User.findOne({
name: decoded.name
}, function (err, user) {
if (err) throw err;
if (!user) {
return res.status(403).send({success: false, msg: 'Authentication failed. User not found.'});
} else {
console.log('Auth for ' + user.name + ' ' + user._id);
return res.send(user._id)
}
});
} else {
return res.status(403).send({success: false, msg: 'No token provided.'});
// return '';
}
});
尝试使用承诺库Bluebird
答案 2 :(得分:1)
詹姆斯的评论看起来像异步电话上的一个好的,彻底的资源。正如其他人所提到的,您无法在回调中返回值。您可以使用Promise库,也可以更改getAuthUserId函数以进行回调并在其中包含console.log逻辑:
示例:
apiRoutes.post('/user/authTestID', function(req, res) {
getAuthUserId(req, res, function(UId) {
// we're in a your new callback
console.log(UId);
if (UId) {
res.sendStatus(200);
}else{
res.sendStatus(400);
}
});
});
// note new callback param
function getAuthUserId(req, res, callback) {
var user = new User();
var token = user.getToken(req.headers);
if (token) {
var decoded = jwt.decode(token, config.secret);
User.findOne({
name: decoded.name
}, function(err, user) {
if (err) throw err;
if (!user) {
res.status(403).send({success: false, msg: 'Authentication failed. User not found.'});
callback(false) // no more return, call callback with value
} else {
console.log('Auth for ' + user.name + ' ' + user._id);
callback(user._id) // no more return, call callback with value
}
});
} else {
res.status(403).send({success: false, msg: 'No token provided.'});
callback(''); // no more return, call callback with value
}
}