Проверьте каждый запрос node.js для аутентификационных данных
Я использую node.js с помощью Express и connect-auth для аутентификации пользователей.
Это проверка при запросе/индексе:
if(req.isAuthenticated()) {
res.redirect('/dashboard');
} else {
res.render('index', { layout: 'nonav' });
}
Однако после выхода из системы и возврата к f.e. '/dashboard', я могу увидеть панель инструментов.
Как я могу поместить проверку проверки подлинности в каждый запрос, чтобы убедиться, что там действительный пользователь все время?
Обновление
У меня нет никаких проблем с аутентификацией, все работает нормально! Мне нужно решение, которое проверяет каждый маршрут/запрос, если есть действительный пользователь, не помещая функцию или if-statement в реализацию маршрута, так как для всего приложения все равно нужен действительный пользователь. Пример Express-Authentication-Example использует "ограничение" в определении маршрута, которое близко, но со многими маршрутами его легко забыть.
Ответы
Ответ 1
app.all('*',function(req,res,next){
if(req.isAuthenticated()){
next();
}else{
next(new Error(401)); // 401 Not Authorized
}
});
// NOTE: depending on your version of express,
// you may need to use app.error here, rather
// than app.use.
app.use(function(err,req,res,next){
// Just basic, should be filled out to next()
// or respond on all possible code paths
if(err instanceof Error){
if(err.message === '401'){
res.render('error401');
}
}
});
Если вы определяете маршрут all
перед маршрутами, для которых требуется аутентификация, а также после маршрутов, которые нет (например, домашняя страница, логин и т.д.), это должно влиять только на маршруты, которые в ней нуждаются. В качестве альтернативы вы можете использовать RegExp вместо '*'
, который будет включать в себя подпуть или список путей, требующих аутентификации.
Другой вариант - создать функцию для включения в каждый маршрут, для которого требуется auth:
function IsAuthenticated(req,res,next){
if(req.isAuthenticated()){
next();
}else{
next(new Error(401));
}
}
app.get('/login',function(req,res,next){
res.render('login');
});
app.get('/dashboard',IsAuthenticated,function(req,res,next){
res.render('dashboard');
});
app.get('/settings',IsAuthenticated,function(req,res,next){
res.render('settings');
});
Ответ 2
Вы можете использовать механизм sessions
, предоставляемый connect
. Поместите этот код в app.configure()
, чтобы включить его:
app.use(express.cookieParser());
app.use(express.session({
secret: 'some string used for calculating hash'
}));
После этого вы сможете использовать объект req.session
(другой для каждого запроса) для хранения ваших данных аутентификации (или чего-либо еще). Итак, ваш пример кода будет выглядеть примерно так:
if (req.session && req.session.authorized) {
res.redirect('/dashboard');
}
else {
res.render('index', {layout: 'nonav'});
}
И проверка подлинности будет выглядеть так:
req.session.authorized = checkPassword(login, passw);
Выход:
req.session.destroy();
Более подробную информацию можно найти здесь.
Ответ 3
Другой способ - использовать функцию промежуточного программного обеспечения. (Пример в CoffeeScript.)
# middleware
authKick = (req, res, next) ->
if not do req.isAuthenticated then return res.redirect '/login'
return do next
# apply
app.use authKick
Это будет работать по каждому запросу без необходимости касаться маршрутов.