Trying to implement the Passport-jwt strategy, I've got it working if I use a string as a 'secret', but I'm struggling to convert it to use a public/private key pair. I've probably made a simple mistake with the keys, but I don't understand what that is.
The login route provides me with a signed token with the pub/priv keys, but is always 'unauthorised' when I try the '/auth/test' route (whereas with the string secret is works)
The code below works, with the non-working code for the pub/priv key code highlighted/commented out.
Any help or comments appreciated!
./controllers/auth.js
exports.login = (req, res, next) => {
(async() => {
try {
const user = await User.findOne({ where: {email: req.body.email} });
if(!user) {
res.status(401).json({ success: false, message: "Bad Username/Password" });
}
const isValid = await bcrypt.compare(req.body.password, user.hashedPassword);
if(isValid) {
const tokenObject = utils.issueJWT(user);
res.status(200).json({ success: true, token: tokenObject.token, expiresIn: tokenObject.expires});
} else {
res.status(401).json({ success: false, message: "Bad Username/Password" });
}
} catch(err) {
next(err);
}
})();
};
./config/passport.js
...
const User = require('../models/user');
// ***** Not working
// const pathToKey = path.join(__dirname, '../../../.ssh/', 'jennings.pub');
// const PUB_KEY = fs.readFileSync(pathToKey, 'utf-8');
// *****
const options = {
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: 'secret',
// ***** Not working
// secretOrKey: PUB_KEY,
// algorithms: ['RS256']
// *****
}
function initialize(passport) {
const authenticateUser = async(jwt_payload, done) => {
let user;
try {
user = await User.findOne({
where: { id: jwt_payload.sub }
});
} catch(e) {
return done(e, false);
}
// No user found
if(!user) {
return done(null, false);
}
// User found
return done(null, user);
};
passport.use(new JwtStrategy(options, authenticateUser));
}
module.exports = initialize;
./util/utils.js
// ***** Not working
// const pathToKey = path.join(__dirname, '../../../.ssh/', 'jennings');
// const PRIV_KEY = fs.readFileSync(pathToKey, 'utf-8');
// *****
exports.issueJWT = (user) => {
const id = user.id;
const expiresIn = '1h';
const payload = {
sub: id,
iat: Date.now()
};
const signedToken = jwt.sign(payload, 'secret', { expiresIn });
// ***** Not working
// const signedToken = jwt.sign(payload, 'secret', { expiresIn, algorithm: 'RS256'});
// *****
return {
token: "" + signedToken,
expires: expiresIn
}
};
The test route
router.get('/test', passport.authenticate('jwt', { session: false }), (req, res, next) => {
res.status(200).json({ success: true, message: 'get in!' });
});