ویژگی تصویر

احراز هویت کاربران در Node.js

  /  Node.js   /  احراز هویت کاربران در Node.js
بنر تبلیغاتی الف
NodeJS - Node.js

احراز هویت کاربران (Authentication) یکی از ارکان اصلی در ساخت اپلیکیشن‌های وب است. در محیط Node.js با توجه به اکوسیستم غنی از ماژول‌ها و فریم‌ورک‌ها، پیاده‌سازی احراز هویت می‌تواند از ساده تا پیچیده متغیر باشد. هدف این مقاله توضیح مفاهیم پایه، نمونه‌های عملی و بهترین شیوه‌های امنیتی است تا بتوانید یک سیستم احراز هویت امن و مقیاس‌پذیر بسازید.

مفاهیم کلیدی

  • تأیید هویت (Authentication): اثبات اینکه کاربر چه کسی است.
  • مجوز (Authorization): اعطای دسترسی به منابع بر اساس نقش‌ها یا مجوزها.
  • Session: ذخیرهٔ وضعیت ورود کاربر در سرور یا دیتابیس.
  • JWT: توکن‌های JSON Web Token برای احراز هویت بدون وضعیت (stateless).
  • OAuth / OpenID Connect: پروتکل‌های استاندارد برای ورود با سرویس‌های ثالث.

الگوهای متداول در Node.js

  • Sessions با express-session و ذخیره‌سازی در Redis یا دیتابیس
  • Token-based با JWT
  • استفاده از Passport.js برای یکپارچه‌سازی استراتژی‌های مختلف (local, oauth)

نمونه عملی: ثبت‌نام و ورود ساده با bcrypt و JWT

const express = require('express');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const bodyParser = require('body-parser');

const app = express();
app.use(bodyParser.json());

const users = []; // برای نمونه - در عمل از دیتابیس استفاده کنید
const JWT_SECRET = 'your-secret-key';
const SALT_ROUNDS = 10;

app.post('/register', async (req, res) => {
  const { username, password } = req.body;
  const hashed = await bcrypt.hash(password, SALT_ROUNDS);
  users.push({ id: users.length + 1, username, password: hashed });
  res.status(201).json({ message: 'user registered' });
});

app.post('/login', async (req, res) => {
  const { username, password } = req.body;
  const user = users.find(u => u.username === username);
  if (!user) return res.status(401).json({ error: 'invalid credentials' });
  const ok = await bcrypt.compare(password, user.password);
  if (!ok) return res.status(401).json({ error: 'invalid credentials' });
  const token = jwt.sign({ sub: user.id, username: user.username }, JWT_SECRET, { expiresIn: '15m' });
  res.json({ token });
});

app.listen(3000);

توضیح: این کد یک API ساده ثبت‌نام و ورود نمایش می‌دهد. رمز عبور با bcrypt هش می‌شود و پس از ورود موفق، یک JWT تولید می‌گردد. در عمل نباید از آرایهٔ حافظه برای ذخیرهٔ کاربر استفاده کنید و کلید مخفی باید از متغیرهای محیطی خوانده شود.

نکات امنیتی برای کد بالا

  • رمز عبور را با bcrypt یا Argon2 هش کنید.
  • کلیدهای مخفی نباید در سورس قرار گیرند؛ از env vars یا secret manager استفاده کنید.
  • برای تولید توکن‌های طولانی‌مدت از refresh token استفاده کنید و آن‌ها را در دیتابیس یا حافظه امن ذخیره کنید.
  • از HTTPS برای تمام ارتباطات استفاده کنید و کوکی‌ها را با HttpOnly و Secure ست کنید.

نمونه: پیاده‌سازی ساده Refresh Token

// assume existing login that issues accessToken and refreshToken
app.post('/token', (req, res) => {
  const { refreshToken } = req.body;
  // validate refreshToken exists in DB and not revoked
  try {
    const payload = jwt.verify(refreshToken, REFRESH_SECRET);
    const accessToken = jwt.sign({ sub: payload.sub }, JWT_SECRET, { expiresIn: '15m' });
    res.json({ accessToken });
  } catch (err) {
    res.status(401).json({ error: 'invalid refresh token' });
  }
});

توضیح: این مسیر یک refresh token را اعتبارسنجی می‌کند و یک access token جدید صادر می‌نماید. توجه کنید که refresh token‌ها معمولاً طولانی‌تر و با طول عمر بیشتر هستند و باید در دیتابیس همراه با وضعیت (مثلاً revoked) نگهداری شوند.

مقایسه سریع: JWT در مقابل Session

ویژگیJWTSession
حالت (Statefulness)StatelessStateful
مقیاس‌پذیریخوب برای سرویس‌های توزیع‌شدهنیاز به سینک/ذخیره‌سازی (Redis)
باطل‌سازی سریع توکنپیچیده‌تر (لیست سیاه یا کوتاه‌مدت)ساده‌تر (حذف session از سرور)

بهترین شیوه‌ها و حملات معمول

  • استفاده از HttpOnly و Secure برای کوکی‌ها تا از سرقت از طریق XSS جلوگیری شود.
  • اجرای rate limiting برای endpointهای ورود با ابزارهایی مثل express-rate-limit.
  • محافظت در برابر CSRF (هنگام استفاده از کوکی) با توکن CSRF یا SameSite=strict.
  • لاگ‌برداری و مانیتورینگ ورودهای ناموفق و تلاش‌های مشکوک.

استفاده از Passport.js و OAuth

اگر می‌خواهید ورود با گوگل، فیسبوک یا سایر ارائه‌دهندگان را اضافه کنید، Passport.js یک راه ساده و استاندارد فراهم می‌کند. Passport دارای استراتژی‌های oauth2 و openidconnect است که پیاده‌سازی ورود ثالث را تسریع می‌کند.

نتیجه‌گیری و توصیه‌های عملی

در اغلب پروژه‌ها توصیه می‌شود:

  • برای اپ‌های کوچک و اپی آی‌های توزیع‌شده از JWT به همراه refresh token استفاده کنید.
  • برای برنامه‌های سنتی web app از session با ذخیره‌سازی امن (مثلاً Redis) بهره ببرید.
  • همیشه رمزها را هش کنید، از HTTPS استفاده کنید و کلیدهای مخفی را ایمن نگه دارید.
  • برای ورود با سرویس‌های خارجی از Passport یا کتابخانه‌های رسمی استفاده کنید تا از پیچیدگی‌های OAuth خلاص شوید.

در صورت نیاز می‌توانم کد کامل یک نمونهٔ production-ready با Redis، refresh-token و Passport را آماده کرده و توضیحات پیاده‌سازی آن را ارائه دهم.

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

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