So I'd like to make some routes in an API that will show different data based on the user role, defined in MongoDB. Here's a sampling of what I have right now, it works...
router.get('/test', passport.authenticate('bearer', {session: false}), function (req, res) {
if (req.user.role == "premium") {
return res.send('you can see this content');
}
else {
return res.send('you can not see this content');
}
})
However, the end goal is to present at least something to the user, even if they're not logged in or authenticated with the right kind of role.
router.get('/test', passport.authenticate('bearer', {session: false}), function (req, res) {
if (req.user.role == "premium") {
return res.send('this is premium content');
}
else {
// could be hit by another role, or no user at all
return res.send([some truncated version of the premium content]);
}
})
Which I would think I'd figure out how to work, but I don't know how to specify the same route which possibly could be hit without any Authorization header in the request.
Is this possible in Passport.js/Express?
I would suggest that you use HTTP status codes and an error object, this is a common API convention and it allows your API users to know what's happening and why:
app.get('/premium-resource', function(req, res, next) {
passport.authenticate('bearer', function(err, user) {
if (user){
if (user.role === 'premium'){
return res.send(200,{userContent:'you are a premium user'});
}else{
return res.send(403,{
'status': 403,
'code': 1, // custom code that makes sense for your application
'message': 'You are not a premium user',
'moreInfo': 'https://myawesomeapi.io/upgrade'
});
}
}else{
return res.send(401,{
'status': 401,
'code': 2, // custom code that makes sense for your application
'message': 'You are not authenticated.',
'moreInfo': 'https://myawesomeapi.io/docs'
});
}
})(req, res, next);
});
Disclaimer: I work at Stormpath and we put a lot of thought into API authentication and design, we have a really presentation on the topic: