我的Node.js服务器上有一个验证路由,用于验证请求:
app.get('/loggedin', auth, function(req, res){
console.log(req.authenticated);
res.send(req.authenticated ? req.authenticated: false)
})
据我了解,auth
在app.get()
之前运行。以下是auth
的代码:
var jwt = require('jsonwebtoken');
var config = require('./config');
module.exports = function(req,res,next){
var bearerHeader = req.headers['authorization'];
var token;
console.log(bearerHeader);
req.authenticated = false;
if (bearerHeader){
console.log("11111");
var bearer = bearerHeader.split(" ");
token = bearer[1];
jwt.verify(token, config.secret, function (err, decoded){
console.log("22222");
if (err){
console.log(err);
req.authenticated = false;
req.decoded = null;
} else {
console.log("33333");
req.decoded = decoded;
req.authenticated = true;
}
});
}
next();
}
但是,在服务器日志中,我收到以下输出:
Bearer jsflkdjlsdfjksodfkjlsdfjkls
11111
false
22222
33333
这意味着客户端有一个令牌,即通过jwt验证。但是,服务器决定在完成在身份验证回调中返回信息之前开始运行app.get()
。是什么给了什么?
答案 0 :(得分:2)
好的,修好了。问题是jwt.verify()
是异步的,因此它不会立即执行。解决这个问题的唯一方法就是在得到任何结果之后调用next()
:
module.exports = function(req,res,next){
var bearerHeader = req.headers['authorization'];
var token;
console.log(bearerHeader);
req.authenticated = false;
if (bearerHeader){
console.log("11111");
var bearer = bearerHeader.split(" ");
token = bearer[1];
jwt.verify(token, config.secret, function (err, decoded){
console.log("22222");
if (err){
console.log(err);
req.authenticated = false;
req.decoded = null;
next();
} else {
console.log("33333");
req.decoded = decoded;
req.authenticated = true;
next();
}
});
}
}
答案 1 :(得分:2)
根据jwt documentation,您可以使用两个选项来实现jwt.verify()
方法:
异步:如果提供了回调,则函数将异步执行。如果签名有效且可选的有效期,受众或发行者有效,则使用解码后的有效负载调用回调。如果没有,它将被错误调用。
// async
jwt.verify(token, pass, (err, decoded) => { async callback } );
同步:如果未提供回调,则函数将同步执行。如果签名有效且可选的有效期限,受众或发行者有效,则返回解码后的有效负载。如果没有,它将引发错误。
//sync
try {
const decoded = jwt.verify(token, pass);
}
catch (ex) { console.log(ex.message); }
答案 2 :(得分:0)
您可以使用同步版本并承诺
const promisify = fn => {
return (...args) => {
return new Promise((resolve, reject) => {
function customCallback(err, ...results) {
if (err) {
return reject(err);
}
return resolve(results.length === 1 ? results[0] : results)
}
args.push(customCallback);
fn.call(this, ...args);
})
}
}
// inside your code for varification
promisify(jwt.verify)(token, process.env.JWT_SECRET)
.then(result => {
console.log(result);
}).catch(err => {
console.log(err);
});
next();