Як працює управління сесіями в Express.js?
Управління сесіями в Express.js
Сесії дозволяють зберігати дані між кількома HTTP-запитами від одного й того ж клієнта. Оскільки HTTP є безстанним, сесії забезпечують стан, зберігаючи дані на сервері та ідентифікуючи клієнта за допомогою куки.
Як працюють сесії
Клієнт Сервер
│ │
│── GET /login ──────────>│
│ │ Створює сесію, зберігає в пам'яті/БД
│<── Set-Cookie: sid=abc──│
│ │
│── GET /dashboard ──────>│ Cookie: sid=abc
│ │ Шукає сесію за "abc"
│<── Панель користувача ──│Використання express-session
bash
npm install express-sessionjs
const session = require('express-session');
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
secure: process.env.NODE_ENV === 'production', // Тільки HTTPS
httpOnly: true, // Не доступно через JavaScript
maxAge: 24 * 60 * 60 * 1000, // 24 години
sameSite: 'lax' // Захист від CSRF
}
}));Використання сесій
js
// Увійти — зберегти користувача в сесії
app.post('/login', async (req, res) => {
const user = await authenticate(req.body);
if (user) {
req.session.userId = user.id;
req.session.role = user.role;
res.json({ message: 'Увійшли' });
} else {
res.status(401).json({ error: 'Невірні облікові дані' });
}
});
// Захищений маршрут — перевірка сесії
app.get('/dashboard', (req, res) => {
if (!req.session.userId) {
return res.status(401).json({ error: 'Не автентифіковано' });
}
res.json({ message: `Ласкаво просимо, користувачу ${req.session.userId}` });
});
// Вийти — знищити сесію
app.post('/logout', (req, res) => {
req.session.destroy((err) => {
if (err) return res.status(500).json({ error: 'Вихід не вдався' });
res.clearCookie('connect.sid');
res.json({ message: 'Вийшли' });
});
});Сховища сесій
За замовчуванням сесії зберігаються в пам'яті (не підходить для виробництва):
| Сховище | Пакет | Найкраще для |
|---|---|---|
| Пам'ять | Вбудоване | Тільки для розробки |
| Redis | connect-redis | Виробництво (швидко, масштабовано) |
| PostgreSQL | connect-pg-simple | Коли ви вже використовуєте Postgres |
| MongoDB | connect-mongo | Коли ви вже використовуєте MongoDB |
js
const RedisStore = require('connect-redis').default;
const { createClient } = require('redis');
const redisClient = createClient({ url: process.env.REDIS_URL });
await redisClient.connect();
app.use(session({
store: new RedisStore({ client: redisClient }),
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false
}));Сесії vs JWT
| Функція | Сесії | JWT |
|---|---|---|
| Зберігання | На стороні сервера | На стороні клієнта (токен) |
| Масштабованість | Потрібно спільне сховище | Безстанне |
| Відкликання | Легко (видалити сесію) | Важко (потрібен чорний список) |
| Розмір | Маленька кука | Більший токен |
| Безпека | Атрибути куки | Перевірка токена |
| Найкраще для | Традиційних веб-додатків | API, SPA, мікросервісів |
Рекомендація: Використовуйте сесії для серверних додатків. Використовуйте JWT для API, що споживаються SPA або мобільними додатками. Для систем великого масштабу використовуйте сесії на основі Redis для легкого горизонтального масштабування.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.