ویژگی تصویر

مدیریت کوکی‌ها در Node.js — راهنمای جامع

  /  Node.js   /  مدیریت کوکی ها در Node.js
بنر تبلیغاتی الف
NodeJS - 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 بهره ببرید.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: