Сессии и flash-сообщения
HTTP не помнит прошлых запросов: каждый приходит к серверу как будто впервые. Сессия — хранилище данных одного посетителя на сервере, которое живёт между его запросами. Браузер получает только cookie с номером сессии и присылает её с каждым запросом, а по номеру сервер находит данные.
Установка и подключение
npm install express-sessionПодключите middleware в src/app.js до маршрутов:
// src/app.js
import session from 'express-session';
app.use(session({
secret: 'замените-на-длинную-случайную-строку',
resave: false,
saveUninitialized: false,
cookie: { httpOnly: true, maxAge: 7 * 24 * 60 * 60 * 1000 },
}));| Опция | Что значит |
|---|---|
secret | Ключ, которым подписывается cookie, чтобы её нельзя было подделать |
resave: false | Не сохранять сессию, если она не менялась |
saveUninitialized: false | Не создавать сессию, пока в неё ничего не записали |
cookie.httpOnly | Cookie недоступна скриптам на странице |
cookie.maxAge | Срок жизни в миллисекундах, здесь неделя |
Запись и чтение
После подключения у каждого запроса есть объект req.session. В него можно записывать любые простые данные:
// src/app.js
app.get('/visits', (req, res) => {
req.session.visits = (req.session.visits ?? 0) + 1;
res.send(`Вы открыли эту страницу ${req.session.visits} раз`);
});Обновляйте /visits — число будет расти. Откройте адрес в другом браузере, и счёт начнётся заново: у него своя сессия.
Flash-сообщения
Flash-сообщение показывается один раз — на странице после перенаправления, например «Статья опубликована». Его записывают в сессию, а middleware переносит в шаблон и сразу удаляет. Создайте src/middleware/flash.js:
// src/middleware/flash.js
export function flash(req, res, next) {
res.locals.flash = req.session.flash;
delete req.session.flash;
next();
}Подключите её после session(): app.use(flash). Теперь в контроллере достаточно записать текст перед перенаправлением:
// src/controllers/postsController.js
export function store(req, res) {
const id = Post.create(req.body);
req.session.flash = 'Статья опубликована';
res.redirect(`/posts/${id}`);
}А в шапке views/partials/header.ejs вывести сообщение, если оно есть:
<% if (locals.flash) { %>
<p class="flash"><%= flash %></p>
<% } %>После публикации над статьёй появится «Статья опубликована», а при обновлении страницы сообщение исчезнет.
Где хранятся данные
По умолчанию express-session держит сессии в памяти процесса: после перезапуска все посетители «забываются», и для работы на настоящем сервере такое хранилище не подходит. В рабочем приложении подключают внешнее хранилище — например Redis или базу данных — через отдельный пакет, который передают в опцию store.
Частая ошибка
Не храните secret прямо в коде, который попадает в Git: зная ключ, можно подделать cookie любого посетителя. Вынесите его в переменную окружения — как это сделать, рассказано в уроке о настройках. В примере выше строка оставлена только для наглядности.