#node.js #express #jwt #ejs
#node.js #экспресс #jwt #ejs
Вопрос:
Я создаю небольшое приложение, в котором пользователь входит в систему и перенаправляется в / profile. Прямо сейчас я извлекаю JWT из localstorage и проверяю его через сервер. Затем сервер отправляет его обратно клиенту, чтобы сообщить мне, является ли это допустимым сеансом или нет.
jQuery / Клиент:
UserController.initPanel = () => {
if (session === null) {
window.location = "/";
} else {
UserController.requestAuth(session);
}
};
UserController.requestAuth = (sessionToken) => {
var settings = {
"url": "/api/auth",
"method": "POST",
"headers": {
"Content-Type": "application/json",
"Authorization": `Bearer ${sessionToken}`,
},
"data": ""
}
$.ajax(settings).done(function (response) {
console.log(response);
});
};
Node.js/auth.js маршрут:
router.post("/", (req, res) => {
const authHeader = req.headers.authorization;
if (typeof authHeader !== 'undefined') {
const bearerToken = authHeader.split(' ')[1];
verifyToken(bearerToken, (authData) => {
tokenRequest(authData, (authResponse) => {
handleAuthResponse(req, res, authResponse);
})
});
}
});
const handleAuthResponse = (req, res, authResponse) => {
console.log(authResponse);
return res.status(200).json(authResponse);
}
const verifyToken = (token, cb) => {
jwt.verify(token, 'mysecret', (err, authData) => {
if (err) {
res.sendStatus(403)
} else {
cb(authData);
}
});
}
const tokenRequest = (authHeader, cb) => {
//console.log(authHeader);
var config = {
headers: {'Authorization': `bearer ${authHeader.token}`}
};
axios.get('https://myapi.dev/api/session/me', config)
.then((res) => {
if (res.data.error) {
return response.data
} else {
cb(res.data);
}
})
.catch((error) => {
console.log('error', error);
});
}
Я чувствую, что это неправильный способ сделать это. Я отрисовываю шаблоны с помощью ejs:
router.get("/profile", (req, res) => {
const settings = {
title: "Profile",
revslider: false
};
res.render("profile/profile", { settings: settings } );
});
И если по какой-либо причине JS отключен, /profile все еще доступен. Это не такая уж большая проблема, просто кажется неправильным.
Итак, возможно ли получить доступ к маршруту / профилю, предварительно проверив авторизацию на стороне сервера перед рендерингом?
Кроме того, auth.js возвращает некоторые пользовательские данные, которые я мог бы использовать в шаблоне .ejs. Так что это еще одна причина, по которой я хотел бы попробовать проверить аутентификацию перед рендерингом.
Редактировать:
Промежуточное ПО аутентификации, которое я не использовал, потому что не был уверен, как передать токен?
module.exports = (req, res, next) => {
try {
const decoded = jwt.verify(req.body.token, 'mysecret');
req.token = decoded;
} catch (error) {
console.log(error);
return res.status(401).json({
message: 'Auth Failed'
});
}
next();
}
Комментарии:
1. Как насчет использования промежуточного программного обеспечения в express (при условии, что это то, что вы используете) и примените это ко всем маршрутам, которые вы хотите защитить.
2. У меня был auth в качестве промежуточного программного обеспечения, но я не был уверен, как передать ему токен сеанса.
3. Токен сеанса будет частью запроса, который всегда передается промежуточному программному обеспечению 🙂 хотите, чтобы я написал базовый пример в качестве ответа?
4. Да, пожалуйста @steadweb
5. Извиняюсь, что не перезвонил тебе, Джесс. Используете ли вы следующий пакет для обработки сеансов? npmjs.com/package/express-session
Ответ №1:
Очень простая middleware
реализация, ниже которой используются express
и express-session
.
Мы в основном создаем простую функцию для проверки req.session
существования внутри этого объекта, у вас может быть что-то, что определяет, действительно ли пользователь прошел аутентификацию. Я бы рекомендовал вам добавить сюда свою собственную логику для дальнейшей проверки статуса пользователя.
const authCheckMiddleware = (req, res, next) => {
// Perform auth checking logic here, which you can attach
// to any route.
if(!req.session) {
return res.redirect('/');
}
next();
};
authCheckMiddleware
Может быть присоединен к любому route
, с помощью app.use
или router.use
. req
Объект передается всему промежуточному программному обеспечению.
// Use the authCheckMiddleware function
router.use('/profile', authCheckMiddleware);
Ваш router.get('/profile')
вызов теперь защищен вышеупомянутым промежуточным программным обеспечением.
// Route protected by above auth check middleware
router.get("/profile", (req, res) => {
const settings = {
title: "Profile",
revslider: false
};
res.render("profile/profile", { settings: settings } );
});
Комментарии:
1. Где «сеанс» проверяет, сохранен ли сеанс через localstorage?
2. Это интерфейс, я концентрируюсь на бэкэнде. Итак, прежде чем вы перейдете к интерфейсу, это должно сработать и перенаправить вас на маршрут входа. Если у вас есть только интерфейсные маршруты, с помощью XHR (AJAX) вам нужно будет вернуть статус 401 и сделать то же самое.