Проверка ролей и аутентификации с помощью Passport.js
Поэтому я хотел бы сделать несколько маршрутов в API, которые будут показывать разные данные на основе роли пользователя, определенной в MongoDB. Здесь выборка того, что у меня есть прямо сейчас, она работает...
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');
}
})
Однако конечная цель состоит в том, чтобы предоставить пользователю что-то, даже если они не вошли в систему или не были аутентифицированы с правильной ролью.
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]);
}
})
Что бы я подумал, что я выясню, как работать, но я не знаю, как указать тот же маршрут, который, возможно, может быть удален без заголовка авторизации в запросе.
Возможно ли это в Passport.js/Express?
Ответы
Ответ 1
Я бы предположил, что вы используете коды состояния HTTP и объект ошибки, это общее соглашение API, и оно позволяет вашим пользователям API знать, что происходит и почему:
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);
});
Отказ от ответственности: я работаю в Stormpath, и мы много размышляем над аутентификацией и дизайном API, у нас есть действительно презентация на тема:
https://stormpath.com/blog/designing-rest-json-apis/
Ответ 2
Решение заключается в ограничении содержимого в представлении, а не в маршруте.
router.get('/test', authenticationMiddleware, function(req, res){
var premiumFlag = req.user.role;
res.send('premiumontent', {role: premiumFlag});
});
premiumContent.jade
p This content is visible to all users
- if role === "premium"
p this content is only visible to premium users
Ответ 3
Решение, которое я нашел в своем ответе, заключается в использовании документации Passportjs.org.
В маршрутах мне нужно возвращать данные, независимо от того, вошел ли пользователь в систему или нет, я могу использовать что-то вроде:
// Test to check for authentication
app.get('/login', function(req, res, next) {
passport.authenticate('bearer', function(err, user, info) {
if (user)
// check user role for premium or not
if (user.role == "premium")
return res.send('user is premium')
else
return res.send('user is not premium');
else
// return items even if no authentication is present, instead of 401 response
return res.send('not logged in');
})(req, res, next);
});