Node.js callback for jwt.verify()
Solution 1
According to jwt documentation you can implement the jwt.verify()
method with two options:
Asynchronous: If a callback is supplied, function acts asynchronously. The callback is called with the decoded payload if the signature is valid and optional expiration, audience, or issuer are valid. If not, it will be called with the error.
// async
jwt.verify(token, pass, (err, decoded) => { async callback } );
Synchronous: If a callback is not supplied, function acts synchronously. Returns the payload decoded if the signature is valid and optional expiration, audience, or issuer are valid. If not, it will throw the error.
//sync
try {
const decoded = jwt.verify(token, pass);
}
catch (ex) { console.log(ex.message); }
Solution 2
Ok just fixed it. The problem is that jwt.verify()
is async, so it won't do it immediately. The only way to get around this to call next()
only after you've got either result:
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();
}
});
}
}
Solution 3
You can use synchronous version and promisify
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();
db2791
Updated on June 20, 2020Comments
-
db2791 almost 4 years
I have an authentication route on my Node.js server that authenticates requests:
app.get('/loggedin', auth, function(req, res){ console.log(req.authenticated); res.send(req.authenticated ? req.authenticated: false) })
As I understand it,
auth
is run beforeapp.get()
. Here is the code forauth
: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(); }
On the server log, however, I receive the following output:
Bearer jsflkdjlsdfjksodfkjlsdfjkls 11111 false 22222 33333
This means that there is a token on the client's side, and that is passes the jwt verification. However, the server decides to begin running
app.get()
before it finishes returning information in the authentication callback. What gives?