Session — express-session, cookie-session
Session nima?
HTTP — "stateless" protokol. Har so'rov mustaqil — server oldingi so'rovni eslamaydi. Foydalanuvchi login qildi, keyingi so'rovda server uni tanımaydi.
Session — serverning foydalanuvchini "eslab qolish" usuli. Login qilganda server session yaratadi, unga ID beradi. ID ni cookie ga saqlaydi. Keyingi so'rovlarda cookie yuboriladi, server session ni topadi.
JWT bilan farqi: JWT da server hech narsa saqlamaydi — ma'lumot tokenning o'zida. Session da esa server ma'lumotni saqlaydi, foydalanuvchiga faqat ID beriladi.
JWT: [foydalanuvchi ma'lumoti token ichida] → server tekshiradi
Session: [faqat ID cookie da] → server ID bo'yicha ma'lumotni topadi
express-session
npm install express-session
const session = require('express-session');
app.use(session({
secret: process.env.SESSION_SECRET, // cookie ni imzolash uchun
resave: false, // o'zgarmagan session ni qayta saqlamaslik
saveUninitialized: false, // bo'sh session ni saqlamaslik
cookie: {
maxAge: 24 * 60 * 60 * 1000, // 1 kun (millisekund)
httpOnly: true, // JavaScript o'qiy olmaydi — XSS dan himoya
secure: process.env.NODE_ENV === 'production', // faqat HTTPS
},
}));
secret — cookie ni imzolash uchun maxfiy kalit. Kimdir cookie ni o'zgartirishga urinsa — imzo mos kelmaydi, server rad etadi.
httpOnly: true — muhim xavfsizlik sozlamasi. JavaScript document.cookie orqali session cookie ni o'qiy olmaydi. XSS hujumidan himoya.
secure: true — cookie faqat HTTPS orqali yuboriladi. Production da har doim.
Session bilan login
router.post('/login', async (req, res, next) => {
try {
const { email, password } = req.body;
const result = await pool.query('SELECT * FROM users WHERE email = $1', [email]);
const user = result.rows[0];
if (!user || !(await bcrypt.compare(password, user.password_hash))) {
return res.status(401).json({ message: 'Email yoki parol noto\'g\'ri' });
}
// Session ga foydalanuvchi ma'lumotini saqlash
req.session.userId = user.id;
req.session.role = user.role;
res.json({ message: 'Kirish muvaffaqiyatli' });
} catch (err) {
next(err);
}
});
// Session tekshiruvchi middleware
function requireAuth(req, res, next) {
if (!req.session.userId) {
return res.status(401).json({ message: 'Login kerak' });
}
next();
}
// Himoyalangan route
router.get('/profile', requireAuth, async (req, res, next) => {
try {
const result = await pool.query(
'SELECT id, name, email FROM users WHERE id = $1',
[req.session.userId]
);
res.json(result.rows[0]);
} catch (err) {
next(err);
}
});
// Logout
router.post('/logout', (req, res) => {
req.session.destroy((err) => {
if (err) return res.status(500).json({ message: 'Xato' });
res.clearCookie('connect.sid'); // session cookie ni o'chirish
res.json({ message: 'Chiqish muvaffaqiyatli' });
});
});
Session saqlash — qayerda?
Standart bo'yicha session xotirada saqlanadi. Bu development uchun yaxshi, lekin production da muammo:
- Server qayta ishga tushsa — barcha session lar yo'qoladi
- Bir nechta server bo'lsa — har biri o'z session larini bilmaydi
Production da session tashqi omborga saqlanadi — Redis eng mashhur tanlov:
npm install connect-redis
const RedisStore = require('connect-redis').default;
const redis = require('./redis');
app.use(session({
store: new RedisStore({ client: redis }),
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: { maxAge: 24 * 60 * 60 * 1000, httpOnly: true, secure: true },
}));
Endi session lar Redis da — server qayta ishga tushsa ham, bir nechta server bo'lsa ham — hammasi bir xil session larni ko'radi.
Session vs JWT — qachon qaysi?
Bu savol ko'p muhokama qilinadi. Qisqacha:
Session — an'anaviy web ilovalar uchun. Server session ni boshqaradi, logout darhol ishlaydi (session o'chiriladi). Lekin bir nechta server bo'lsa — tashqi saqlash kerak.
JWT — API lar, mobil ilovalar, microservices uchun. Server hech narsa saqlamaydi — masshtablash oson. Lekin logout qiyin — token muddati o'tguncha amal qiladi.
Web ilova (server-side render) → Session
REST API, mobil ilova → JWT
Tez-tez uchraydigan xatolar
secret ni kod ichiga yozish:
// Xato:
app.use(session({ secret: 'mysecret' }));
// To'g'ri:
app.use(session({ secret: process.env.SESSION_SECRET }));
Production da secure: true unutish:
secure: true bo'lmasa — cookie HTTP orqali ham yuboriladi. Odam-o'rtada hujumida ushlab olinishi mumkin.
Xotirada session saqlash (production da):
// Xato — production da:
app.use(session({ /* store yo'q */ }));
// Server qayta ishga tushsa — barcha foydalanuvchilar qayta login qilishi kerak
Xulosa
Session — server foydalanuvchini eslab qoladi. ID cookie da, ma'lumot serverda. httpOnly va secure — muhim xavfsizlik sozlamalari.
Production da session Redis da saqlanadi — bir nechta server va qayta ishga tushishda muammo bo'lmaydi.
JWT — server hech narsa saqlamaydi, masshtablash oson. Session — logout darhol ishlaydi, an'anaviy web uchun.
Keyingi dars
25-dars: Cookie — cookie-parser, httpOnly, secure, sameSite