I have initialized strategy for JWT:
const jwtStrategyOptions = {
jwtFromRequest: ExtractJwt.fromHeader('x-access-token'),
secretOrKey: 'publicKey',
}
passport.use(
new JwtStrategy(
jwtStrategyOptions,
(payload, done) => {
MySQL.Users.readOne(['id'], { id: payload.userId })
.fork(
error => {console.log(error)
done(error)},
user => {
console.log(user)
done(null, user)}
)
}
)
)
And middleware:
const isAuthenticated: RequestHandler = (req, res, next) => {
passport.authenticate(
'jwt',
{ session: false, failWithError: true },
(error, user) => {
//error is null when I pass empty payload
if (error) {
return next(error)
}
req.user = user
return next()
}
)(req, res, next)
}
But when I pass empty or invalid token Passport just pass this
(payload, done) => {
MySQL.Users.readOne(['id'], { id: payload.userId })
.fork(
error => {console.log(error)
done(error)},
user => {
console.log(user)
done(null, user)}
)
}
step and code execute next()
function.
Can I somehow detect that payload is invalid or empty?
I'm not quite sure about the MySQL call return type, but if nothing matches the id, does it raise an error?
(payload, done) => {
MySQL.Users.readOne(['id'], { id: payload.userId })
.fork(
error => {console.log(error)
done(error)},
user => {
console.log(user)
done(null, user)}
)
}
If it doesn't raise an error but return null or empty value, you need to check it in the 'success' callback function, because in this case it will call done(null, user)
with an empty value.
Based on your comment, this might help, some code that I was using to check for a token expiration error :
passport.authenticate('jwt',
{session: false},
//we need this callback to return information on why it's failing
//err is not populated, but 'info' is...
(err, user, info) => {
if (err) {
return next(err);
}
//if we couldn't authenticate the user, check why
//401 is used when no token or random information is provided
//403 is used when a well-formed token is provided, but it has expired thus not valid anymore
if (!user) {
if (info.name === 'TokenExpiredError') {
return res.status(403).send(info.name);
}
else {
return res.status(401).send(info.message);
}
}
req.user = user;
return next();