در یکی از پرونده‌های امنیتی که سال گذشته بررسی کردم، یک شرکت متوسط با نشتی داده روبرو شده بود که ریشه آن در یک اشتباه ساده در احراز هویت REST API بود: توکن JWT (JSON Web Token) بدون اعتبارسنجی signature ذخیره می‌شد و فقط محتوای payload آن بررسی می‌شد. مهاجم با تغییر payload و بدون تغییر signature، خودش را به عنوان یک کاربر admin معرفی کرده بود. این تجربه نشان می‌دهد که احراز هویت در REST API، فراتر از یک توکن ساده است؛ یک سیستم چندلایه است که هر لایه باید درست پیاده شود. در این مقاله، بر اساس تجربه‌های مهندسی و استانداردهای OWASP، این حوزه را در عمق بررسی می‌کنم.

طبق گزارش Salt Security API Security Report، بیش از ۹۰ درصد از سازمان‌ها در سال گذشته با مشکل امنیت API مواجه شده‌اند و ۴۱ درصد از حملات به API از طریق احراز هویت معیوب انجام شده. OWASP API Security Top 10 در نسخه ۲۰۲۳، دو آسیب‌پذیری از ده آسیب‌پذیری اصلی را مستقیماً مرتبط با احراز هویت و مجوزدهی می‌داند: API1 (Broken Object Level Authorization) و API2 (Broken Authentication). این آمار نشان می‌دهد که احراز هویت REST API، یکی از پرخطرترین حوزه‌های امنیت وب است. اگر با مفاهیم پایه‌ای REST آشنا نیستید، پیشنهاد می‌کنم ابتدا REST API چیست و اصول طراحی REST API را مطالعه کنید.

چالش‌های احراز هویت در REST بی‌حالت

یکی از محدودیت‌های بنیادین REST، Stateless بودن است. یعنی سرور نباید وضعیت کلاینت را بین درخواست‌ها نگه دارد. اما احراز هویت ذاتاً یک مفهوم Stateful است: کاربر یک بار احراز هویت می‌کند و سپس در درخواست‌های بعدی شناخته می‌شود. این تنش بنیادین، چالش‌های متعددی ایجاد می‌کند.

راه‌حل‌های مختلف برای این تنش وجود دارد: API Key که یک شناسه ثابت است، Session که Stateful است، JWT که اطلاعات را در توکن کدگذاری می‌کند، و OAuth که یک framework برای احراز هویت و مجوزدهی است. هر راه‌حل، مزایا و معایب خودش را دارد و انتخاب باید بر اساس سناریو باشد.

یک نکته مهم: Stateless بودن REST به معنای نبود State در سرور نیست؛ به معنای نبود State درخواست در سرور است. سرور می‌تواند State داشته باشد (مثل دیتابیس کاربران)، اما نباید State بین درخواست‌های مختلف یک کاربر را نگه دارد. این تفکیک، در طراحی صحیح احراز هویت REST API اهمیت دارد. اگر با اصول بی‌حالتی آشنا نیستید، اصول طراحی معماری وب مدرن را مطالعه کنید.

احراز هویت در REST، حل کردن تنش بین Stateless بودن درخواست و Stateful بودن هویت است. هر راه‌حل، یک تعادل متفاوت بین امنیت، سادگی و مقیاس‌پذیری ارائه می‌دهد.

API Key و Basic Auth

API Key و Basic Authentication ساده‌ترین راه‌حل‌های احراز هویت در REST API هستند. API Key، یک رشته یکتا است که به هر کلاینت اختصاص داده می‌شود. این رشته، معمولاً در هدر یا پارامتر درخواست ارسال می‌شود.

GET /api/users
X-API-Key: abc123def456ghi789

مزایای API Key: سادگی پیاده‌سازی، سازگاری با همه زبان‌ها و فریمورک‌ها، و کارایی بالا (چون نیازی به محاسبات رمزنگاری نیست). عیب‌های آن: امنیت محدود (اگر لو برود، مهاجم به همه دسترسی‌ها دست پیدا می‌کند)، عدم انقضا، عدم امکان ابطال سریع، و عدم امکان محدودسازی دقیق.

Basic Authentication روش قدیمی‌تری است که در RFC 7617 تعریف شده. در این روش، نام کاربری و رمز عبور با Base64 کدگذاری و در هدر Authorization ارسال می‌شود:

GET /api/users
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

نکته حیاتی: Basic Auth فقط بر بستر HTTPS امن است. در HTTP، رمز عبور به صورت قابل خواندن منتقل می‌شود. اما حتی در HTTPS، Basic Auth برای APIهای عمومی توصیه نمی‌شود، چون هر درخواست رمز عبور را ارسال می‌کند و این باعث افزایش سطح حمله می‌شود.

توصیه من: API Key برای APIهای داخلی، سیستم‌های بین‌سرویسی یا ورودی‌های عمومی مناسب است. Basic Auth فقط در سناریوهای خاص مثل تست یا APIهای بسیار ساده منطقی است. برای APIهای جدی، OAuth 2.0 یا JWT انتخاب‌های بهتر هستند. اگر به امنیت API علاقه‌مندید، امنیت API و چگونه REST API امن بسازیم را بخوانید.

OAuth 2.0 و OIDC

OAuth 2.0 یکی از استانداردترین و قدرتمندترین frameworkهای احراز هویت و مجوزدهی است که در RFC 6749 تعریف شده. نسخه ۲.۰ این framework، در سال ۲۰۱۲ منتشر شد و امروز پایه احراز هویت در اکثر APIهای بزرگ (Google، Facebook، GitHub و...) است.

OAuth 2.0 چهار نقش اصلی دارد: Resource Owner (کاربر)، Client (اپلیکیشن)، Authorization Server (سرور احراز هویت) و Resource Server (سرور API). جریان کار OAuth 2.0 شامل چند مرحله است: کلاینت از Resource Owner اجازه می‌گیرد، Authorization Server یک Access Token صادر می‌کند، کلاینت با این توکن به Resource Server درخواست می‌فرستد.

OAuth 2.0 چهار Grant Type اصلی دارد: Authorization Code (برای اپلیکیشن‌های وب با backend)، Implicit (منسوخ شده)، Client Credentials (برای ارتباط بین سرویس‌ها)، و Resource Owner Password Credentials (برای اپلیکیشن‌های trusted). در ۲۰۲۶، Authorization Code با PKCE (Proof Key for Code Exchange) استاندارد پیشنهادی برای اکثر سناریوهاست.

OIDC (OpenID Connect) یک لایه احراز هویت روی OAuth 2.0 است که در سال ۲۰۱۴ معرفی شد. OAuth 2.0 فقط مجوزدهی است، یعنی می‌گوید کلاینت به چه منابعی دسترسی دارد. OIDC احراز هویت را اضافه می‌کند، یعنی می‌گوید کاربر کیست. تفاوت این دو، در تفاوت احراز هویت و مجوزدهی و OAuth چیست و چگونه کار می‌کند بررسی شده است.

مزایای OAuth 2.0 و OIDC: اول، امکان اعطای دسترسی محدود (Scoped Access). دوم، امکان ابطال توکن. سوم، امکان Refresh Token برای دریافت توکن جدید بدون احراز هویت مجدد. چهارم، پشتیبانی از چند کلاینت با یک حساب کاربری. پنجم، استانداردسازی شده و ابزارهای بالغ دارد.

عیب‌های OAuth 2.0: اول، پیچیدگی پیاده‌سازی. دوم، نیاز به یک Authorization Server جداگانه (که می‌تواند هزینه‌بر باشد). سوم، در برخی سناریوها (مثل اپلیکیشن‌های موبایل بومی)، پیچیدگی بیشتر است. اما برای پروژه‌های جدی و APIهای عمومی، مزایا بر معایب می‌چربد. اگر می‌خواهید OAuth را در پروژه خود پیاده کنید، راهنمای بهترین روش‌های احراز هویت کاربران را ببینید.

JWT به تفصیل

JWT (JSON Web Token) یکی از رایج‌ترین مکانیزم‌های احراز هویت در REST API است که در RFC 7519 تعریف شده. JWT یک توکن خودتوصیف (Self-Contained) است که شامل سه بخش است: Header، Payload و Signature. این سه بخش با نقطه (.) جدا شده و به صورت Base64URL کدگذاری شده‌اند.

Header: {"alg": "HS256", "typ": "JWT"}
Payload: {"sub": "1234567890", "name": "محمد رضایی", "iat": 1516239022}
Signature: HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

JWT کامل: eyJhbGci...eyJzdWIi...SflKxwRJSM...

JWT دو نوع امضا دارد: Symmetric (با HMAC و یک کلید مشترک) و Asymmetric (با RSA یا ECDSA و جفت کلید عمومی/خصوصی). در سناریوی اول، همان کلید برای امضا و اعتبارسنجی استفاده می‌شود. در سناریوی دوم، کلید خصوصی برای امضا و کلید عمومی برای اعتبارسنجی استفاده می‌شود. سناریوی دوم برای معماری‌های توزیع‌شده بهتر است، چون Resource Server نیازی به کلید خصوصی ندارد.

مزایای JWT: اول، Stateless است و نیازی به ذخیره session در سرور ندارد. دوم، شامل اطلاعات کاربر است و نیازی به query به دیتابیس در هر درخواست نیست. سوم، قابل استفاده در معماری‌های توزیع‌شده است. چهارم، در همه زبان‌ها و فریمورک‌ها پشتیبانی می‌شود.

عیب‌های JWT: اول، ابطال توکن دشوار است. چون Stateless است، سرور نمی‌تواند یک JWT را در میانه عمرش ابطال کند، مگر اینکه لیست سیاه (Blacklist) نگه دارد که خودش Stateful است. دوم، حجم JWT معمولاً بیشتر از Session ID است. سوم، اگر Payload حجیم باشد، حجم درخواست‌ها افزایش می‌یابد. چهارم، در صورت لو رفتن کلید امضا، همه توکن‌های صادرشده معتبر فرض می‌شوند.

اشتباهات رایج در استفاده از JWT: اول، ذخیره اطلاعات حساس در Payload. JWT به صورت Base64URL کدگذاری شده و هر کسی می‌تواند Payload را بخواند. باید اطلاعات عمومی مثل user id و scope در Payload ذخیره شوند، نه رمز عبور یا شماره کارت. دوم، استفاده از الگوریتم none. JWT از الگوریتم none پشتیبانی می‌کند که به معنای بدون امضا است. این الگوریتم باید در سرور مسدود شود. سوم، اعتبارسنجی نکردن Signature. همان‌طور که در داستان ابتدای این مقاله دیدیم، عدم اعتبارسنجی signature می‌تواند فاجعه‌بار باشد. اگر با JWT آشنا نیستید، JWT چیست و چه کاربردی در احراز هویت دارد را مطالعه کنید.

یک نکته مهم درباره عمر JWT: توصیه استاندارد، عمر کوتاه (۱۵ دقیقه تا ۱ ساعت) برای Access Token و عمر بلندتر (روزها یا هفته‌ها) برای Refresh Token است. این رویکرد، تعادل بین امنیت و تجربه کاربری را حفظ می‌کند. اگر Access Token لو برود، مهاجم فقط برای زمان محدودی می‌تواند از آن استفاده کند. Refresh Token اجازه می‌دهد کاربر بدون احراز هویت مجدد، Access Token جدید بگیرد.

Session و Cookies در REST

استفاده از Session و Cookies در REST API یک موضوع بحث‌برانگیز است. از منظر خالص REST، Session Stateful است و در تضاد با اصل Stateless قرار دارد. اما در عمل، بسیاری از APIها از Session با Cookies استفاده می‌کنند، چون ساده‌تر است و امکان ابطال فوری را فراهم می‌کند.

رویکرد Session-based: سرور یک Session ID تولید می‌کند، آن را در دیتابیس یا cache ذخیره می‌کند، و در کوکی به کلاینت می‌فرستد. در درخواست‌های بعدی، کلاینت این Session ID را در کوکی ارسال می‌کند و سرور بر اساس آن، کاربر را شناسایی می‌کند. در این رویکرد، سرور Stateful است (Session در سرور ذخیره می‌شود).

پیکربندی درست کوکی برای API:

Set-Cookie: session_id=abc123; HttpOnly; Secure; SameSite=Strict; Path=/api

در این پیکربندی، HttpOnly جلوی دسترسی JavaScript به کوکی را می‌گیرد (محافظت در برابر XSS). Secure فقط ارسال از طریق HTTPS را اجازه می‌دهد. SameSite=Strict جلوی ارسال کوکی در درخواست‌های cross-origin را می‌گیرد (محافظت در برابر CSRF).

مزایای Session-based: امکان ابطال فوری، امکان ذخیره اطلاعات پیچیده در Session، و امکان پیاده‌سازی ساده. عیب‌های آن: Stateful است و نیاز به ذخیره‌سازی مرکزی دارد (مثل Redis یا دیتابیس)، در معماری‌های توزیع‌شده پیچیده‌تر است، و در سناریوهایی که کلاینت از دامنه دیگری است (مثل اپلیکیشن موبایل)، مدیریت کوکی مشکل‌ساز می‌شود.

توصیه من: برای APIهای وب داخلی، Session-based می‌تواند انتخاب مناسبی باشد. برای APIهای عمومی، موبایل و بین‌سرویسی، JWT یا OAuth 2.0 انتخاب‌های بهتری هستند. اگر به مباحث امنیتی علاقه‌مندید، راهنمای هدرهای امنیتی HTTP را ببینید.

mTLS و امنیت Service-to-Service

mTLS (Mutual TLS) یک رویکرد پیشرفته برای احراز هویت است که در آن، هم کلاینت و هم سرور یکدیگر را با گواهی دیجیتال احراز هویت می‌کنند. این رویکرد، به ویژه در معماری‌های میکروسرویس و سناریوهای Service-to-Service بسیار مؤثر است.

در mTLS، هر سرویس یک گواهی دیجیتال دارد که توسط یک CA (Certificate Authority) داخلی صادر شده. در هنگام ارتباط، هم سرویس مبدأ و هم سرویس مقصد گواهی خود را ارائه می‌دهند و یکدیگر را اعتبارسنجی می‌کنند. این رویکرد، از حملات MITM و سرقت توکن جلوگیری می‌کند، چون مهاجم نمی‌تواند به گواهی معتبر دسترسی داشته باشد.

مزایای mTLS: اول، احراز هویت قوی در سطح شبکه. دوم، عدم نیاز به مدیریت توکن. سوم، مناسب برای معماری‌های Zero Trust. چهارم، استانداردسازی شده و در Service Meshها مثل Istio و Linkerd پشتیبانی می‌شود. عیب‌های آن: پیچیدگی مدیریت گواهی‌ها (Certificate Rotation، Revocation) و نیاز به زیرساخت PKI (Public Key Infrastructure).

در ۲۰۲۶، mTLS به تدریج به استاندارد در معماری‌های میکروسرویس تبدیل می‌شود. طبق گزارش Istio، بیش از ۷۰ درصد از سازمان‌هایی که از Service Mesh استفاده می‌کنند، mTLS را در ارتباطات داخلی خود پیاده‌سازی کرده‌اند. اگر با معماری میکروسرویس آشنا نیستید، تفاوت معماری مونولیتیک و میکروسرویس و تفاوت VPS و هاست اشتراکی را مطالعه کنید.

WebAuthn و Passkeys

WebAuthn یک استاندارد مدرن برای احراز هویت است که توسط W3C و FIDO Alliance تدوین شده. این استاندارد، احراز هویت بدون رمز عبور (Passwordless) را ممکن می‌کند و در برابر فیشینگ بسیار مقاوم است. WebAuthn در REST API از طریق مکانیزم چالش-پاسخ (Challenge-Response) پیاده‌سازی می‌شود.

جریان کار WebAuthn در REST API: اول، کلاینت از سرور یک چالش درخواست می‌کند. دوم، سرور یک چالش تصادفی تولید می‌کند و آن را برمی‌گرداند. سوم، کلاینت از دستگاه امنیتی (مثل Touch ID یا YubiKey) می‌خواهد که این چالش را با کلید خصوصی کاربر امضا کند. چهارم، کلاینت پاسخ امضاشده را به سرور می‌فرستد. پنجم، سرور امضا را با کلید عمومی کاربر اعتبارسنجی می‌کند.

مزایای WebAuthn: اول، مقاومت در برابر فیشینگ. کلید خصوصی هرگز از دستگاه خارج نمی‌شود، بنابراین حتی اگر کاربر روی سایت فیشینگ هم کلیک کند، مهاجم نمی‌تواند به کلید دسترسی داشته باشد. دوم، تجربه کاربری ساده‌تر (ورود با اثر انگشت یا تشخیص چهره). سوم، استانداردسازی شده و در مرورگرهای مدرن پشتیبانی می‌شود.

عیب‌های WebAuthn: اول، پیچیدگی پیاده‌سازی در سمت سرور. دوم، نیاز به fallback برای کاربرانی که دستگاه‌شان از WebAuthn پشتیبانی نمی‌کند. سوم، چالش‌های بازیابی حساب در صورت گم شدن دستگاه. اما با وجود این عیب‌ها، WebAuthn به تدریج به استاندارد احراز هویت در اپلیکیشن‌های حساس تبدیل می‌شود. اگر به این حوزه علاقه‌مندید، تأثیر 2FA بر امنیت و فعال‌سازی 2FA برای کاربران وردپرس را ببینید.

مجوزدهی: RBAC, ABAC و Scope

احراز هویت و مجوزدهی دو مفهوم متفاوت هستند که در پروژه‌ها زیاد با هم اشتباه گرفته می‌شوند. احراز هویت یعنی پاسخ به سؤال کاربر کیست. مجوزدهی یعنی پاسخ به سؤال کاربر چه کاری می‌تواند انجام دهد. در REST API، مجوزدهی معمولاً با سه مدل انجام می‌شود: RBAC، ABAC و Scope.

RBAC (Role-Based Access Control) ساده‌ترین و رایج‌ترین مدل مجوزدهی است. در این مدل، هر کاربر یک یا چند نقش (Role) دارد و هر نقش مجموعه‌ای از مجوزها دارد. مثلاً نقش admin به همه چیز دسترسی دارد، نقش editor به محتوا، و نقش viewer فقط به خواندن.

ABAC (Attribute-Based Access Control) مدل پیچیده‌تر و انعطاف‌پذیرتری است که بر اساس ویژگی‌های کاربر، منبع، عملیات و شرایط تصمیم می‌گیرد. مثلاً کاربران می‌توانند فقط سفارش‌های خودشان را ببینند؛ این تصمیم بر اساس ویژگی owner بودن کاربر روی منبع گرفته می‌شود.

Scope مدل رایج در OAuth 2.0 است. در این مدل، هر Access Token با یک یا چند Scope (مثل read:users، write:orders) صادر می‌شود و کلاینت فقط می‌تواند در محدوده این Scopeها عمل کند. این رویکرد، به ویژه برای APIهای عمومی مفید است، چون کاربر می‌تواند دسترسی دقیق به هر اپلیکیشن بدهد.

نکته مهم درباره مجوزدهی: مشکل API1 در OWASP API Security Top 10، Broken Object Level Authorization (BOLA) است که به معنای نبود کنترل دسترسی در سطح منبع است. مثلاً یک API ممکن است کاربر را احراز هویت کند، اما بررسی نکند که آیا این کاربر مجاز به دسترسی به سفارش مشخصی هست یا نه. این آسیب‌پذیری، یکی از رایج‌ترین دلایل نشتی داده در APIهاست. اگر به این حوزه علاقه‌مندید، تفاوت احراز هویت و مجوزدهی و آسیب‌پذیری IDOR را مطالعه کنید.

امنیت توکن: نگهداری، عمر و ابطال

امنیت توکن، یکی از پرچالش‌ترین حوزه‌های احراز هویت REST API است. سه جنبه اصلی: نگهداری (Storage)، عمر (Lifetime) و ابطال (Revocation).

نگهداری توکن: در مرورگر، سه گزینه اصلی وجود دارد: LocalStorage، SessionStorage و HttpOnly Cookie. LocalStorage و SessionStorage در دسترس JavaScript هستند و بنابراین در برابر XSS آسیب‌پذیرند. HttpOnly Cookie از JavaScript پنهان است، اما در برابر CSRF آسیب‌پذیر است. هیچ‌کدام از این گزینه‌ها کامل نیستند. رویکرد رایج و امن‌تر، ترکیب چند لایه است: Access Token کوتاه‌عمر در حافظه (Memory)، Refresh Token در HttpOnly Cookie با SameSite، و CSRF Token برای محافظت اضافی.

عمر توکن: Access Token باید عمر کوتاه داشته باشد (۱۵ دقیقه تا ۱ ساعت)، تا در صورت لو رفتن، خسارت محدود باشد. Refresh Token می‌تواند عمر بیشتری داشته باشد (روزها یا هفته‌ها)، اما باید در هر استفاده چرخش کند (Refresh Token Rotation) تا در صورت لو رفتن، فقط یک بار قابل استفاده باشد.

ابطال توکن: در JWT، ابطال توکن چالشی اساسی است. سه رویکرد رایج: اول، استفاده از Blacklist که لیست توکن‌های ابطال‌شده را نگه می‌دارد. دوم، استفاده از Allowlist که فقط توکن‌های فعال را نگه می‌دارد. سوم، استفاده از توکن‌های کوتاه‌عمر که با Refresh Token تازه می‌شوند و ابطال از طریق ابطال Refresh Token انجام می‌شود. رویکرد سوم استاندارد پیشنهادی امروز است.

نکات امنیتی توکن: اول، توکن‌ها باید با TLS منتقل شوند. دوم، توکن‌ها نباید در URL پارامتر باشند (چون در log سرور و history مرورگر ثبت می‌شوند). سوم، توکن‌ها نباید در فایل‌های لاگ یا پیام‌های خطا نمایش داده شوند. چهارم، توکن‌های ابطال‌شده باید در اولین فرصت پاک شوند. مباحث بیشتر در امن‌سازی لاگین ادمین و اصول مدیریت رمز عبور امن آمده است.

OWASP API Security Top 10

OWASP API Security Top 10 یک مرجع مهم برای آسیب‌پذیری‌های امنیتی APIهاست که در نسخه ۲۰۲۳ منتشر شده. دو آسیب‌پذیری از ده آسیب‌پذیری اصلی، مستقیماً مرتبط با احراز هویت و مجوزدهی هستند.

کدآسیب‌پذیریمثال
API1Broken Object Level Authorizationدسترسی به سفارش کاربر دیگر
API2Broken Authenticationاحراز هویت معیوب با JWT نامعتبر
API3Broken Object Property Level Authorizationدسترسی به فیلدهای حساس
API4Unrestricted Resource Consumptionنبود Rate Limiting
API5Broken Function Level Authorizationدسترسی به endpointهای admin
API6Unrestricted Access to Sensitive Business Flowsسوءاستفاده از فرم‌های حساس
API7Server Side Request Forgeryدسترسی سرور به منابع داخلی
API8Security Misconfigurationپیش‌فرض‌های ناامن
API9Improper Inventory ManagementAPIهای قدیمی نصب‌شده
API10Unsafe Consumption of APIsاعتماد بی‌جا به APIهای خارجی

نکته مهم درباره BOLA: این آسیب‌پذیری در سال‌های اخیر صدرنشین OWASP API Security Top 10 بوده و طبق آمار، مسئول بیش از ۴۰ درصد از حملات به API است. راه‌حل آن: بررسی دقیق دسترسی در سطح منبع. یعنی هر بار که کاربر به یک منبع درخواست دسترسی می‌کند، سرور باید بررسی کند که آیا این کاربر مالک یا مجاز به دسترسی به این منبع است یا نه. این بررسی نباید به کلاینت سپرده شود.

Zero Trust در احراز هویت API

مدل Zero Trust در احراز هویت REST API به معنای اعتماد نداشتن به هیچ درخواست، حتی از داخل شبکه است. در این مدل، هر درخواست باید مستقل احراز هویت و مجوزدهی شود، بدون توجه به منبع آن.

اصول Zero Trust در احراز هویت API: اول، احراز هویت مداوم (Continuous Authentication) که شامل بررسی توکن در هر درخواست است. دوم، حداقل دسترسی (Least Privilege) که هر کلاینت فقط به منابعی که نیاز دارد دسترسی دارد. سوم، میکرو-سگمنتیشن (Micro-segmentation) که دسترسی‌ها را در سطح شبکه محدود می‌کند. چهارم، پایش مداوم که هر درخواست مشکوک را شناسایی می‌کند.

پیاده‌سازی Zero Trust در APIها شامل سه لایه است: لایه احراز هویت (Authentication) که با JWT، OAuth 2.0 یا mTLS انجام می‌شود. لایه مجوزدهی (Authorization) که با RBAC، ABAC یا Scope انجام می‌شود. لایه پایش (Monitoring) که شامل Logging، Rate Limiting و Anomaly Detection است. اگر به این حوزه علاقه‌مندید، راهنمای امنیت وردپرس و اشتباهات رایج امنیت وب را مطالعه کنید.

پرسش‌های پرتکرار درباره احراز هویت REST API

JWT بهتر است یا Session؟ بستگی به سناریو دارد. JWT برای APIهای عمومی، اپلیکیشن‌های موبایل و معماری‌های توزیع‌شده بهتر است. Session برای APIهای داخلی و وب‌سایت‌های سنتی ساده‌تر است. در ۲۰۲۶، ترکیب هر دو (Access Token کوتاه‌عمر + Refresh Token مبتنی بر Session) رویکرد رایجی است.

آیا API Key امن است؟ API Key برای APIهای داخلی و سیستم‌های بین‌سرویسی در محیط‌های امن می‌تواند مناسب باشد. اما برای APIهای عمومی، به تنهایی امن نیست، چون اگر لو برود، مهاجم به همه دسترسی‌ها دست پیدا می‌کند. API Key باید حتماً با HTTPS و در صورت امکان با یک لایه اضافی (مثل IP Allowlist) ترکیب شود.

چگونه JWT را ابطال کنم؟ سه رویکرد: Blacklist (نگهداری توکن‌های ابطال‌شده)، Allowlist (نگهداری توکن‌های فعال)، یا توکن‌های کوتاه‌عمر که با Refresh Token تازه می‌شوند. رویکرد سوم استاندارد پیشنهادی است، چون تعادل بین امنیت و Stateless بودن را حفظ می‌کند.

آیا OAuth 2.0 برای پروژه‌های کوچک مناسب است؟ OAuth 2.0 پیچیدگی بالایی دارد و برای پروژه‌های کوچک، ممکن است بیش از حد باشد. اگر پروژه کوچک است و تیم تجربه OAuth ندارد، JWT یا Session می‌تواند انتخاب بهتری باشد. اما اگر پروژه قصد رشد دارد، سرمایه‌گذاری روی OAuth 2.0 منطقی است.

تفاوت OAuth 2.0 و OIDC چیست؟ OAuth 2.0 یک framework مجوزدهی است (یعنی می‌گوید کلاینت به چه منابعی دسترسی دارد). OIDC یک لایه احراز هویت روی OAuth 2.0 است (یعنی می‌گوید کاربر کیست). OIDC از OAuth 2.0 برای احراز هویت استفاده می‌کند و اطلاعات کاربر را در قالب ID Token برمی‌گرداند.

چگونه از JWT در برابر XSS محافظت کنم؟ JWT را در HttpOnly Cookie ذخیره کنید، نه در LocalStorage. اگر JWT را در حافظه (Memory) نگه می‌دارید، از Refresh Token در HttpOnly Cookie استفاده کنید. این رویکرد، بهترین تعادل بین امنیت و تجربه کاربری را ارائه می‌دهد.

آیا mTLS برای همه پروژه‌ها مناسب است؟ mTLS برای معماری‌های میکروسرویس و سناریوهای Service-to-Service بسیار مؤثر است. اما برای اپلیکیشن‌های عمومی (وب یا موبایل)، پیچیدگی مدیریت گواهی‌ها می‌تواند بیش از حد باشد. در این سناریوها، OAuth 2.0 یا JWT انتخاب‌های بهتری هستند.

آنچه باید با خود ببرید

احراز هویت در REST API یک حوزه پیچیده و چندلایه است. انتخاب مکانیزم مناسب، بستگی به سناریو، سطح امنیت مورد نیاز، و بلوغ تیم دارد. از API Key ساده تا OAuth 2.0 پیچیده، هر مکانیزم نقاط قوت و ضعف خودش را دارد.

هفت اصل کلیدی که در این مقاله بررسی شد:

  1. احراز هویت در REST بی‌حالت، نیازمند مکانیزم‌های Self-Contained مثل JWT است.
  2. API Key و Basic Auth برای سناریوهای ساده، اما نه برای APIهای عمومی.
  3. OAuth 2.0 و OIDC استاندارد پیشنهادی برای APIهای عمومی و جدی.
  4. JWT باید با اعتبارسنجی signature، عمر کوتاه و بدون اطلاعات حساس استفاده شود.
  5. مجوزدهی سطح منبع (Object Level) ضروری است و نباید به کلاینت سپرده شود.
  6. OWASP API Security Top 10 مرجع اصلی آسیب‌پذیری‌های امنیتی API است.
  7. مدل Zero Trust، رویکرد پیشنهادی برای احراز هویت در محیط‌های ابری.

قدم عملی امروز: به APIهای موجود خود نگاه کنید و سه بررسی انجام دهید. اول، آیا JWT شما با اعتبارسنجی signature استفاده می‌شود؟ دوم، آیا مجوزدهی در سطح منبع انجام می‌شود؟ سوم، آیا Rate Limiting فعال است؟ این سه بررسی، بخش بزرگی از OWASP API Security Top 10 را پوشش می‌دهد. اگر می‌خواهید عمیق‌تر شوید، امنیت API و چگونه REST API امن بسازیم را مطالعه کنید.

اگر تجربه‌ای در پیاده‌سازی احراز هویت REST API در پروژه‌های واقعی داشتید — به‌خصوص اگر با چالشی مثل ابطال JWT یا مهاجرت از Session به JWT مواجه شده‌اید — در دیدگاه‌ها بنویسید. این تجربه‌ها برای خواننده‌های بعدی بسیار ارزشمند خواهند بود. 🔐