I'm using express
and it's router
to create a server with a public and private routes. To access the private route user must sign in and send the JWT
token. The token is fine but I can't redirect the user to the private route.
const express = require('express');
const jwt = require('jsonwebtoken');
const authRouter = require('./auth');
const usersRouter = require('./users');
const router = express.Router();
router.use(authRouter);
const accessTokenSecret = '4-8-15-16-23-42';
const privateRoutes = ['/user'];
const checkPublicOrPrivate = (req, res, next) => {
privateRoutes.forEach(route => {
if (req.path.includes(route)) {
return authorization(req, res, next);
}
});
return next();
};
const authorization = (req, res, next) => {
const { token } = req.headers;
if (token) {
jwt.verify(token, accessTokenSecret, (err, user) => {
if (err) {
return res.status(403).send('Forbiden, access denied');
}
console.log(user); //{ username: 'username', iat: 1603288443 }
return next(); //Should go to the next middleware
});
}
return res.status(403).send('Bad message') //But always hits this message or the 404 one
};
router.use(checkPublicOrPrivate);
router.use(authorization); //Also tried without this line
router.use(usersRouter);
router.use(function(req, res, next) {
res.status(404).send('404 not found!');
});
router.use(function(err, req, res, next) {
res.status(500).send('Server error');
});
module.exports = router;
That's because jwt.verify
is asynchronous (it has a callback function).
While your token is being verified, the code execution goes on. Next line to be executed is res.status(403).send('Bad message')
, so it is always executed.
The solution is to wrap the line in an else
statement
const authorization = (req, res, next) => {
const { token } = req.headers;
if (token) {
jwt.verify(token, accessTokenSecret, (err, user) => {
if (err) {
return res.status(403).send('Forbiden, access denied');
}
console.log(user);
return next();
});
} else { // add 'else'
res.status(403).send('Bad message'); // This line will only be executed if there's no token
}
};