Как настроить сессии в Express (Node.js)

О чём эта статья
- Что такое сессия и почему так важно хранить чувствительные данные на сервере.
- Как быстро создать Node.js-проект и подключить express-session.
- Лучшие практики безопасности и варианты реализации для продакшена.
Что вам понадобится
- Node.js и npm (любая недавняя версия). Node.js обычно уже содержит npm.
- Командная строка для инициализации проекта и установки пакетов.
- Базовое понимание JavaScript и Express.
Что такое сессия в Node.js
Cookie — это маленький файл, который браузер хранит у себя. Его удобно использовать для простых предпочтений пользователя (например, тема или язык). Но хранить в cookie логины или пароли нельзя. Cookies пересылаются по сети и могут быть перехвачены, а также сохраняются в явном виде на клиенте.
Сессия — это способ хранить данные на сервере и связывать их с конкретным пользователем через идентификатор (sessionID), который обычно передаётся в cookie. Сервер хранит чувствительные данные (логин, email, привилегии) в своём хранилище, а клиенту отправляется только маркер доступа. Это безопаснее и даёт централизованный контроль.
Краткое определение: Сессия — это запись на сервере, привязанная к уникальному sessionID, который хранится в cookie клиента.
Быстрая демонстрация: создание сессий в Express
Ниже — пошаговая инструкция для простого примера.
1. Создайте проект Node.js
Откройте терминал, создайте папку для проекта и перейдите в неё:
mkdir express-session-demo
cd express-session-demoИнициализируйте проект:
npm init -yЭто создаст package.json с настройками по умолчанию.
2. Установите зависимости
Установите Express и express-session:
npm i express express-sessionДля продакшена вы также добавите хранилище сессий (например, connect-redis, connect-mongo и т. п.).
3. Создайте сервер и подключите сессии
Создайте файл App.js в корне проекта и импортируйте зависимости:
const express = require('express');
const session = require('express-session');
const app = express();
app.use(express.json());Зарегистрируйте middleware для сессий. Здесь показан минимальный пример для локальной разработки:
app.use(
session({
secret: 'some secret',
cookie: { maxAge: 30000 },
saveUninitialized: false,
resave: false
})
);Пояснения к основным опциям:
- secret — строка для подписи cookie с sessionID. Должна быть надёжной в продакшене.
- cookie.maxAge — время жизни cookie в миллисекундах (здесь 30 000 = 30 секунд).
- saveUninitialized: false — не сохраняет пустые сессии; важно для логинов.
- resave: false — не сохраняет сессию на сервере, если она не изменилась.
Добавим маршрут логина для примера. Ожидаем JSON с полями username и password:
app.post('/login', (req, res) => {
const { username, password } = req.body;
if (username && password) {
if (req.session.authenticated) {
res.json(req.session);
} else {
if (password === '123') {
req.session.authenticated = true;
req.session.user = { username, password };
res.json(req.session);
} else {
res.status(403).json({ msg: 'Bad credentials' });
}
}
} else {
res.status(403).json({ msg: 'Bad credentials' });
}
});Запустите сервер:
app.listen(3000, () => {
console.log('Server is running on port 3000');
});Пример запроса из REST‑клиента (JSON):
POST http://localhost:3000/login
Content-Type: application/json
{ "username": "Kingsley", "password": "123" }Если всё правильно, сервер вернёт объект с полем cookie и данными сессии.
Важное замечание: в примере мы сохраняем пароль в сессии в целях демонстрации. В реальном приложении храните только то, что действительно нужно (обычно username и идентификатор пользователя). Пароли не должны храниться в сессии.
Почему сессии улучшают UX
Сессии позволяют серверу помнить пользователя между запросами. Это нужно для авторизации, управления корзиной покупок, корзины оформления заказа, персонализации и т. п. Без сессий приложение должно использовать сторонние механизмы для связывания состояния с пользователем, что усложняет архитектуру.
Лучшие практики безопасности
Важно не полагаться на базовую конфигурацию для продакшена. Ниже — список практических мер.
- Используйте надёжный secret и храните его во внешнем менеджере секретов.
- Не используйте MemoryStore в продакшене. Подключите Redis, MongoDB или другой внешний store.
- Устанавливайте флаги cookie: httpOnly: true, secure: true (для HTTPS), sameSite: ‘lax’ или ‘strict’.
- Ограничьте время жизни сессии и применяйте ротацию идентификаторов после успешного входа.
- Реализуйте защиту от CSRF (токены или SameSite).
- Минимизируйте информацию в сессии: храните только идентификатор и необходимые атрибуты.
- Логируйте и мониторьте аномалии (многочисленные попытки входа, слишком частая смена сессий).
Пример безопасной конфигурации cookie:
app.use(
session({
secret: process.env.SESSION_SECRET,
store: new RedisStore({ client: redisClient }),
cookie: {
maxAge: 1000 * 60 * 60 * 2, // 2 часа
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax'
},
saveUninitialized: false,
resave: false
})
);Альтернативы и когда сессии не подходят
- JWT (JSON Web Tokens). Подход без состояния: сервер доверяет подписанным токенам. Подходит для распределённых API и microservices. Минусы: сложнее отозвать токен; нужно продумывать механизм аннулирования.
- OAuth/OIDC. Используется для авторизации через провайдеров (Google, GitHub). Подходит для SSO.
- Local Storage / sessionStorage. Хранить токены в localStorage ненадёжно из‑за XSS. Не рекомендуется для чувствительных токенов.
Когда не использовать сессии:
- Если у вас полностью статeless API, и клиенты сами управляют токенами.
- Если вы не можете обеспечить защищённое хранилище сессий в продакшене (например, нет отказоустойчивого store).
Модель мышления: cookie vs session
- Cookie = контейнер в браузере. Хранит небольшие данные и идентификатор.
- Session = запись на сервере. Содержит реальные данные о пользователе.
- SessionID связывает cookie и сессию. Клиент хранит только ключ; сервер хранит содержимое.
Эта модель помогает быстро принимать архитектурные решения: если данные чувствительные — храните на сервере.
Хранилища сессий и миграция
MemoryStore реализованный в express-session не предназначен для продакшена. Для устойчивости и масштабирования используйте:
- Redis (connect-redis) — быстрое хранилище в памяти, часто используется для сессий.
- MongoDB (connect-mongo) — если у вас уже есть MongoDB.
- SQL‑база (например, sequelize-store) — если ваша архитектура SQL‑ориентирована.
Мини-методология миграции:
- Подключите выбранный store в тестовом окружении.
- Настройте TTL (время жизни) сессий и политику очистки.
- Проведите нагрузочное тестирование и проверьте поведение при перезапуске приложения.
- Перенесите трафик на новый store, мониторьте метрики.
Роль‑ориентированные чеклисты
Для разработчика:
- Проверил, что secret хранится в env-переменной.
- Не храню пароли в сессии.
- Добавил httpOnly и sameSite для cookie.
Для DevOps:
- Развернул Redis/Mongo с резервированием.
- Настроил бэкапы и мониторинг.
- Настроил масштабируемость и отказоустойчивость.
Для безопасности:
- Включил HTTPS и secure‑cookie в продакшене.
- Реализовал CSRF‑защиту.
- Провёл аудит логики управления сессиями.
Критерии приёмки
- Приложение создаёт сессию после успешного входа и возвращает sessionID в cookie.
- При повторном запросе со старой cookie сервер узнаёт пользователя.
- Сессии удаляются после истечения maxAge или при выходе из системы.
- В продакшене используется внешний store (Redis/Mongo). MemoryStore запрещён.
- Параметры cookie: httpOnly = true, secure = true (в prod), sameSite установлен.
Шаблон конфигурации (cheat sheet)
// Пример express-session с Redis
const session = require('express-session');
const RedisStore = require('connect-redis')(session);
app.use(
session({
store: new RedisStore({ client: redisClient }),
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: { httpOnly: true, secure: true, sameSite: 'lax', maxAge: 1000*60*60 }
})
);Тесты и сценарии приёмки
- Попытка входа с пустым логином/паролем — 403.
- Успешный вход возвращает authenticated = true и user.
- После истечения maxAge сессия недействительна.
- Попытка использовать устаревший sessionID не даёт доступа.
Короткая сводка по безопасности
- Всегда используйте HTTPS.
- Не храните в сессии пароли.
- Выбирайте устойчивое хранилище и контролируйте TTL.
- Обновляйте sessionID (регулярная ротация) после повышения прав.
1‑строчная глоссарий
- Cookie — файл в браузере, содержащий небольшие данные или идентификатор.
- Session — запись на сервере с данными о пользователе.
- sessionID — ключ, связывающий cookie и сессию на сервере.
- Store — хранилище сессий (Redis, MongoDB и т. п.).
- httpOnly — флаг cookie, запрещающий доступ через JavaScript.
- secure — флаг cookie, разрешающий передачу только по HTTPS.
Примеры, когда такой подход не работает
- Высоконагруженные распределённые системы, где легко масштабировать без центрального хранилища — там чаще применяют JWT и stateless‑архитектуру.
- Если вы не можете гарантировать безопасное хранение sessionID или секретов.
Короткое резюме
Сессии в Express — простой и надёжный способ хранить состояние пользователя на сервере. Для разработки достаточно express-session, но в продакшене обязательно используйте внешний store, безопасные cookie и политики защиты от CSRF и XSS. Если вы выбираете между сессиями и JWT, ориентируйтесь на требования к отзыву токенов и распределённости архитектуры.
Важно: сохраняйте только необходимую информацию в сессии и всегда тестируйте поведение при истечении срока годности и при перезапуске сервисов.
Похожие материалы
Разбиение кода в React: как, зачем и когда
Интеграция Google в Windows 8
Родительский контроль Windows 8 — как настроить
Цветовое кодирование дорожек в Logic Pro X
Пользовательские типы записей в WordPress — Event