مدیریت کوکی ها در Node.js
کوکیها یکی از اصلیترین ابزارها برای نگهداری وضعیت در وب هستند. در Node.js مدیریت صحیح کوکیها برای امنیت، حریم خصوصی و عملکرد اپلیکیشن اهمیت زیادی دارد. در این مقاله به مفاهیم پایه، تنظیمات حیاتی، مثالهای عملی با Express و هدایای امنیتی مثل HttpOnly، SameSite و رمزنگاری میپردازیم.
چرا کوکی و چه زمانی از آن استفاده کنیم؟
- ذخیره session id و نگهداری احراز هویت بین درخواستها.
- ذخیره تنظیمات کاربر (مثل زبان) که نیاز به امنیت بالایی ندارند.
- ردگیری موقت وضعیت؛ اما به دلیل محدودیت اندازه و مسائل حریم خصوصی نباید دادههای حساس در کوکی ذخیره شود.
مفاهیم کلیدی کوکی
- HttpOnly: مانع دسترسی جاوااسکریپت کلاینت به کوکی میشود (کاهش حملات XSS).
- Secure: کوکی فقط روی HTTPS ارسال میشود.
- SameSite: کنترل ارسال کوکی در درخواستهای بینسایتی (Lax, Strict, None).
- Max-Age / Expires: زمان حیات کوکی.
- Domain / Path: دامنه و مسیرهایی که کوکی فرستاده میشود.
نمونه ساده با Express و cookie-parser
const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();
app.use(cookieParser('your-secret-here')); // for signed cookies
app.get('/set', (req, res) => {
res.cookie('sessionId', 'abc123', {
httpOnly: true,
secure: true,
sameSite: 'lax',
maxAge: 1000 * 60 * 60 // 1 hour
});
res.send('Cookie set');
});
app.get('/get', (req, res) => {
res.send(req.cookies); // unsigned cookies
});
app.get('/set-signed', (req, res) => {
res.cookie('user', 'john', { signed: true, httpOnly: true });
res.send('Signed cookie set');
});
app.get('/get-signed', (req, res) => {
res.send(req.signedCookies);
});
app.listen(3000);این کد مثالی از استفاده cookie-parser در Express است. در /set کوکی استاندارد با HttpOnly، Secure و SameSite ست میشود. در /set-signed کوکی امضاشده ساخته میشود تا تغییر غیرمجاز شناسایی شود.
وقتی signed کافی نیست — رمزنگاری محتوا
کوکیهای امضا شده فقط یکپارچگی را تضمین میکنند اما محتوا قابل خواندن است. برای محرمانگی باید محتوای کوکی را رمزنگاری کنید.
const crypto = require('crypto');
const algorithm = 'aes-256-gcm';
const key = crypto.randomBytes(32); // store/manage securely
const iv = crypto.randomBytes(12);
function encrypt(text) {
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update(text, 'utf8', 'base64');
encrypted += cipher.final('base64');
const tag = cipher.getAuthTag().toString('base64');
return `${iv.toString('base64')}:${tag}:${encrypted}`;
}
function decrypt(payload) {
const [ivB64, tagB64, encrypted] = payload.split(':');
const iv = Buffer.from(ivB64, 'base64');
const tag = Buffer.from(tagB64, 'base64');
const decipher = crypto.createDecipheriv(algorithm, key, iv);
decipher.setAuthTag(tag);
let dec = decipher.update(encrypted, 'base64', 'utf8');
dec += decipher.final('utf8');
return dec;
}این توابع مثال سادهای از رمزنگاری AES-GCM برای نگهداری محرمانگی محتوای کوکی هستند. توجه کنید که مدیریت کلید (key) بسیار مهم است — نباید در کد ثابت قرار گیرد و حتماً از مخزن امن (مثل AWS KMS یا Vault) استفاده شود.
قواعد و بهترین شیوهها
- تا حد امکان فقط شناسه سشن در کوکی ذخیره کنید؛ دادههای حجیم یا حساس را در سرور یا دیتابیس نگه دارید.
- برای کوکیهایی که نیاز به ارسال بین دامنهها دارند،
SameSite=NoneوSecureرا ست کنید (اما مراقب ریسکها باشید). - کوکیها را با HttpOnly مشخص کنید تا XSS نتواند آنها را بدزدد.
- برای احراز هویت، از توکنهای JWT در کوکی استفاده میشود اما JWT طولانی است؛ بهتر است فقط id ذخیره شود و دادهها سمت سرور بررسی شود یا JWT در HttpOnly cookie ذخیره و با CSRF token محافظت شود.
- در محیط تولید از ذخیرهساز نشست مناسب (Redis، دیتابیس) استفاده کنید و از memory store پیشفرض Express-session صرفاً برای توسعه بهره ببرید.
نمونه غیرایمن و اصلاحشده
// insecure: storing user object directly
res.cookie('user', JSON.stringify({id:1, role:'admin'}));
// improved: store only session id and keep user data on server
res.cookie('sid', sessionId, { httpOnly: true, secure: true, sameSite: 'lax' });
// server: lookup sessionId in Redis/dbذخیره شیء کاربر در خود کوکی خطرناک است (سو استفاده و تغییر). بهجای آن فقط شناسه سشن ذخیره کنید و دادهها را از سرور بارگذاری کنید.
محدودیتها و نکات عملکردی
- کوکیها معمولاً تا حدود 4KB محدود هستند؛ به همین خاطر دادههای بزرگ را در کوکی قرار ندهید.
- هر درخواست به سرور تمام کوکیهای مرتبط را ارسال میکند که میتواند پهنایباند را افزایش دهد؛ کوکیهای غیرضروری را حذف کنید.
- کوکیهای سرتاسری برای CDN و منابع استاتیک میتوانند باعث کندی شوند؛ مسیر و دامنه را محدود کنید.
سیاستهای امنیتی تکمیلی
- از پیشوندهای امن مرورگر استفاده کنید:
- __Secure- — فقط روی HTTPS و با Secure.
- __Host- — نیازمند Secure، Path=”/” و بدون Domain.
- CSRF: اگر از کوکی برای احراز هویت استفاده میکنید، حتماً از توکن CSRF یا sameSite مناسب بهره ببرید.
- نوسازی کلیدها: کلیدهای امضا/رمزنگاری را دورهای بچرخانید و نسخهبندی کنید تا کوکیهای قدیمی بتوانند اعتبارسنجی شوند یا منقضی شوند.
جدول مرجع ویژگیهای مهم کوکی
| ویژگی | توضیح |
|---|---|
| HttpOnly | ممانعت از دسترسی جاوااسکریپت |
| Secure | ارسال فقط روی HTTPS |
| SameSite | کنترل ارسال در درخواستهای بینسایتی (Lax/Strict/None) |
| Domain/Path | محدودسازی دامنه و مسیر |
| Max-Age/Expires | مدت زمان حیات کوکی |
جمعبندی و توصیه نهایی
کوکیها ابزار قدرتمندی برای مدیریت وضعیت در برنامههای Node.js هستند اما اگر به درستی پیکربندی نشوند، میتوانند خطرات امنیتی و عملکردی ایجاد کنند. بهترین رویکرد این است که:
- فقط اطلاعات ضروری را در کوکی ذخیره کنید (ترجیحاً یک session id).
- همیشه HttpOnly و Secure را برای کوکیهای حساس فعال کنید.
- برای محافظت در برابر CSRF از SameSite یا توکن CSRF استفاده کنید.
- برای محرمانگی از رمزنگاری صحیح و مدیریت امن کلیدها بهره ببرید.
- در محیط تولید از store های مقیاسپذیر (مثل Redis) برای سشنها استفاده کنید.
با رعایت این نکات میتوانید از کوکیها به شکلی امن، کارا و سازگار با حریم خصوصی کاربران در اپلیکیشنهای Node.js بهره ببرید.
آیا این مطلب برای شما مفید بود ؟




