15 روز قبل

JWT؛ کلید احراز هویت امن

JWT Authentication چیست؟ آموزش JWT به زبان ساده

 
فرض کنید وارد یک سایت می‌شوید، نام کاربری و رمز عبور خود را وارد می‌کنید و با موفقیت وارد حساب کاربری‌تان می‌شوید. از این لحظه به بعد، وقتی به صفحه پروفایل یا یک API دسترسی پیدا می‌کنید، سرور از کجا می‌فهمد که این درخواست متعلق به شماست؟
 
آیا باید در هر درخواست دوباره رمز عبورتان را ارسال کنید؟ قطعاً نه!
 
اینجاست که مفهوم Authentication، Token و JWT اهمیت پیدا می‌کند.
 
🔐 JWT Authentication یکی از روش‌های رایج برای پیاده‌سازی احراز هویت و انتقال اطلاعات قابل اعتبارسنجی بین بخش‌های مختلف یک سیستم است و به‌خصوص در APIها، برنامه‌های تحت وب، اپلیکیشن‌های موبایل و معماری‌های مدرن کاربرد زیادی دارد.
 

JWT چیست؟

 
JWT مخفف JSON Web Token است.
 
JWT یک فرمت استاندارد برای ساخت توکن‌هایی است که می‌توانند اطلاعاتی را بین دو طرف، معمولاً کلاینت و سرور، به شکلی قابل اعتبارسنجی منتقل کنند.
 
به زبان ساده، می‌توان JWT را شبیه یک کارت شناسایی دیجیتال در نظر گرفت.
 
برای مثال، کاربر وارد سایت می‌شود و اطلاعات ورود خود را ارسال می‌کند:
 
Username: ali
Password: 123456
 
سرور اطلاعات را بررسی می‌کند. اگر صحیح باشند، یک JWT ایجاد کرده و آن را به کاربر برمی‌گرداند.
 
از این به بعد، کاربر می‌تواند در درخواست‌های بعدی توکن خود را ارسال کند تا سرور بتواند اعتبار درخواست را بررسی کند.
 

نکته مهم درباره JWT

 
JWT معمولی رمزگذاری‌شده (Encrypted) نیست.
 
اطلاعات داخل Header و Payload معمولاً فقط با Base64URL کدگذاری شده‌اند و قابل خواندن هستند. چیزی که به امنیت و اعتبارسنجی JWT کمک می‌کند، Signature یا امضای توکن است.
 
بنابراین نباید اطلاعات محرمانه‌ای مانند رمز عبور، شماره کارت بانکی یا اطلاعات حساس کاربران را داخل Payload قرار داد.
 

JWT Authentication چگونه کار می‌کند؟

 
روند کلی استفاده از JWT معمولاً به این شکل است:
 

1. کاربر وارد حساب کاربری می‌شود

 
کاربر نام کاربری و رمز عبور خود را برای سرور ارسال می‌کند.
 

2. سرور اطلاعات را بررسی می‌کند

 
سرور اطلاعات ارسال‌شده را با اطلاعات ثبت‌شده در سیستم مقایسه می‌کند.
 
اگر اطلاعات صحیح باشند، احراز هویت موفق خواهد بود.
 

3. سرور JWT ایجاد می‌کند

 
پس از ورود موفق، سرور یک JWT ایجاد می‌کند.
 
برای مثال:
 
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

4. توکن به کاربر ارسال می‌شود

 
سرور JWT را در پاسخ به کلاینت ارسال می‌کند.
 

5. کاربر در درخواست‌های بعدی توکن را ارسال می‌کند

 
برای مثال، هنگام درخواست به یک API، توکن می‌تواند در Header قرار بگیرد:
 
Authorization: Bearer eyJhbGciOi...
 
عبارت Bearer به این معناست که کلاینت توکن را به‌عنوان اعتبار دسترسی همراه درخواست ارسال کرده است.
 

6. سرور JWT را بررسی می‌کند

 
سرور Signature، زمان انقضا و سایر اطلاعات مورد نیاز را بررسی می‌کند.
 
اگر توکن معتبر باشد، درخواست می‌تواند ادامه پیدا کند.
 

به‌صورت ساده:

 
ورود کاربر
     ↓
بررسی Username و Password
     ↓
ایجاد JWT
     ↓
ارسال JWT به کاربر
     ↓
ارسال JWT در درخواست‌های بعدی
     ↓
اعتبارسنجی Token
     ↓
دسترسی به API

ساختار JWT چگونه است؟

 
هر JWT معمولاً از سه بخش تشکیل می‌شود:
 
Header.Payload.Signature
 
این سه بخش با نقطه . از یکدیگر جدا می‌شوند.
 

1. Header

 
Header اطلاعاتی درباره توکن و الگوریتم مورد استفاده برای امضای آن را مشخص می‌کند.
 
برای مثال:
 
{
  "alg": "HS256",
  "typ": "JWT"
}
 
در این مثال:
 
alg الگوریتم امضای توکن را مشخص می‌کند.
typ نوع توکن را مشخص می‌کند.

2. Payload

 
Payload شامل اطلاعاتی است که قرار است داخل توکن قرار بگیرند.
 
برای مثال:
 
{
  "sub": "123",
  "role": "admin",
  "exp": 1786272000
}
 
ممکن است اطلاعاتی مانند موارد زیر در Payload قرار بگیرند:
 
شناسه کاربر
نقش کاربر
زمان ایجاد توکن
زمان انقضا
صادرکننده توکن
 
این اطلاعات را اصطلاحاً Claims می‌نامیم.
 
⚠️ نکته امنیتی
 
Payload رمزگذاری نشده است.
 
پس قرار دادن اطلاعات حساس مانند:
 
Password
Credit Card Number
Private Information
 
داخل آن کار درستی نیست.
 

3. Signature

 
Signature یا امضا برای اعتبارسنجی توکن استفاده می‌شود.
 
به زبان ساده، سرور با استفاده از اطلاعات JWT و کلید مورد اعتماد، امضایی ایجاد می‌کند.
 
اگر شخصی Payload را تغییر دهد، Signature دیگر با اطلاعات جدید مطابقت نخواهد داشت و سرور می‌تواند متوجه تغییر غیرمجاز شود.
 
بنابراین بهتر است بگوییم:
 
Signature به سرور کمک می‌کند تغییر غیرمجاز در توکن را تشخیص دهد.
 

یک مثال ساده از ساخت JWT

 
برای درک بهتر، فرض کنید در Node.js از یک کتابخانه JWT استفاده می‌کنیم:
 
const jwt = require("jsonwebtoken");
 
const token = jwt.sign(
  { userId: 123, role: "admin" },
  process.env.JWT_SECRET,
  { expiresIn: "1h" }
);
 
console.log(token);
 
در این مثال:
 
userId شناسه کاربر است.
role نقش کاربر را مشخص می‌کند.
JWT_SECRET کلید مورد استفاده برای امضای توکن است.
expiresIn مدت اعتبار توکن را مشخص می‌کند.
 
خروجی چیزی شبیه یک JWT خواهد بود:
 
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
 
البته در پروژه واقعی باید از روش‌های امن برای مدیریت Secret استفاده کرد و نباید کلیدهای حساس را مستقیماً داخل کد قرار داد.
 

Access Token چیست؟

 
یکی از مفاهیمی که هنگام یادگیری JWT با آن روبه‌رو می‌شوید، Access Token است.
 
Access Token توکنی است که معمولاً برای دسترسی به منابع محافظت‌شده یا APIها استفاده می‌شود.
 
برای مثال:
 
GET /api/profile
Authorization: Bearer <access-token>
 
Access Token معمولاً عمر نسبتاً کوتاهی دارد.
 
دلیل این موضوع این است که اگر توکن به هر دلیلی در اختیار فرد دیگری قرار گرفت، مدت سوءاستفاده از آن محدودتر باشد.
 

Refresh Token چیست؟

 
گاهی اوقات نمی‌خواهیم کاربر مجبور شود مرتب دوباره وارد حساب خود شود.
 
در چنین شرایطی می‌توان از Refresh Token استفاده کرد.
 

به زبان ساده:

 
Access Token: برای دسترسی به API
 
Refresh Token: برای دریافت Access Token جدید
 
یک روند ساده می‌تواند این‌گونه باشد:
 
Login
  ↓
Access Token + Refresh Token
  ↓
Access Token برای درخواست‌های API
  ↓
Access Token منقضی می‌شود
  ↓
ارسال Refresh Token
  ↓
دریافت Access Token جدید
 
این روش باعث می‌شود بتوان Access Token را کوتاه‌مدت نگه داشت و در عین حال تجربه کاربری مناسبی ایجاد کرد.
 
البته پیاده‌سازی Refresh Token نیازمند طراحی امنیتی مناسب و مدیریت صحیح چرخه عمر توکن‌هاست.
 

JWT در درخواست API چگونه استفاده می‌شود؟

 
فرض کنید کاربر می‌خواهد اطلاعات پروفایل خود را دریافت کند.
 
کلاینت می‌تواند چنین درخواستی ارسال کند:
 
GET /api/profile
Authorization: Bearer eyJhbGciOi...
 
سرور سپس مواردی مانند زیر را بررسی می‌کند:
 
آیا توکن ساختار معتبر دارد؟
آیا Signature معتبر است؟
آیا توکن منقضی نشده است؟
آیا صادرکننده و مخاطب توکن در صورت استفاده صحیح هستند؟
آیا کاربر اجازه دسترسی به این منبع را دارد؟
 
اگر همه بررسی‌های مورد نیاز موفق باشند، سرور اطلاعات مورد نظر را برمی‌گرداند.
 

مزایای JWT چیست؟

 
JWT به دلایل مختلفی در پروژه‌های مدرن محبوب شده است.
 

🚀 1. مناسب برای معماری Stateless

 
در معماری‌های Stateless، سرور می‌تواند بدون نگهداری Session سنتی برای هر کاربر، توکن را اعتبارسنجی کند.
 

🌐 2. مناسب برای APIها

 
JWT در ارتباط بین Front-end و Back-end و همچنین APIهای مختلف کاربرد زیادی دارد.

 

📱 3. قابل استفاده در اپلیکیشن‌های موبایل

 
اپلیکیشن‌های موبایل نیز می‌توانند از Token برای احراز هویت درخواست‌های خود استفاده کنند.
 

☁️ 4. مناسب برای سیستم‌های توزیع‌شده

 
در معماری‌هایی که چند سرویس یا چند سرور وجود دارند، توکن قابل اعتبارسنجی می‌تواند در شرایط مناسب استفاده شود.
 

🔄 5. قابل حمل بودن

 
JWT به شکل یک رشته متنی منتقل می‌شود و می‌تواند در محیط‌ها و فناوری‌های مختلف استفاده شود.
 

معایب و محدودیت‌های JWT چیست؟

 
JWT با وجود مزایای زیاد، همیشه بهترین انتخاب نیست.
 

⚠️ 1. لغو فوری توکن می‌تواند پیچیده باشد

 
اگر یک JWT هنوز منقضی نشده باشد، لغو فوری آن نسبت به Session می‌تواند به راهکارهای تکمیلی نیاز داشته باشد.
 

⚠️ 2. سرقت Token خطرناک است

 
اگر مهاجم به یک Token معتبر دسترسی پیدا کند، ممکن است بتواند از آن برای دسترسی به منابع محافظت‌شده استفاده کند.
 

⚠️ 3. حجم Token

 
اگر اطلاعات زیادی داخل Payload قرار دهید، اندازه JWT افزایش پیدا می‌کند و در هر درخواست، داده بیشتری منتقل خواهد شد.
 

⚠️ 4. مدیریت نادرست Token

 
ذخیره‌سازی یا ارسال نادرست Token می‌تواند امنیت سیستم را کاهش دهد.
 
به همین دلیل استفاده از JWT بدون توجه به اصول امنیتی، به‌تنهایی به معنی داشتن یک سیستم امن نیست.
 

نکات مهم امنیت JWT

 
اگر قرار است از JWT در یک پروژه واقعی استفاده کنید، رعایت چند نکته بسیار مهم است:
 

🔐 از HTTPS استفاده کنید

 
توکن‌ها باید در ارتباطات امن منتقل شوند. استفاده از HTTPS به محافظت از اطلاعات هنگام انتقال کمک می‌کند.
 

⏳ زمان انقضای مناسب تعیین کنید

 
Access Token معمولاً نباید بدون دلیل برای مدت بسیار طولانی معتبر باشد.
 

🔑 Secret را امن نگه دارید

 
کلیدهای مورد استفاده برای امضای JWT نباید در کد عمومی یا Repository قرار بگیرند.
 

🚫 اطلاعات حساس داخل Payload قرار ندهید

 
JWT معمولی رمزگذاری نشده است؛ بنابراین Payload مکان مناسبی برای اطلاعات محرمانه نیست.
 

🔄 Refresh Token را با دقت مدیریت کنید

 
Refresh Token معمولاً حساس‌تر است و باید با مکانیزم‌های امنیتی مناسب محافظت شود.
 

🛡️ توکن را در محل امن نگهداری کنید

 
محل ذخیره‌سازی Token باید بر اساس معماری برنامه و تهدیدهای امنیتی انتخاب شود. در برنامه‌های وب، انتخاب بین Cookieهای امن و سایر روش‌ها باید با توجه به مواردی مانند XSS و CSRF انجام شود.
 

JWT چه کاربردهایی دارد؟

 
JWT را می‌توان در سناریوهای مختلفی مشاهده کرد، از جمله:
 
💻 احراز هویت کاربران در وب‌سایت‌ها
📱 احراز هویت اپلیکیشن‌های موبایل
🌐 ارتباط بین Front-end و Back-end
🔌 محافظت از APIها
☁️ برخی معماری‌های Microservices
🔐 مدیریت دسترسی به منابع محافظت‌شده
 
البته استفاده از JWT به معنی مناسب بودن آن برای تمام این سناریوها نیست و معماری پروژه باید در تصمیم‌گیری نقش داشته باشد.
 

آیا JWT همیشه بهترین انتخاب است؟

خیر.
 
JWT یک ابزار قدرتمند است، اما انتخاب فناوری احراز هویت باید بر اساس نیاز پروژه انجام شود.
 
برای مثال اگر پروژه شما به مدیریت ساده Session، کنترل مرکزی Sessionها یا لغو فوری دسترسی نیاز داشته باشد، استفاده از Session می‌تواند گزینه مناسبی باشد.
 
در پروژه‌های API محور یا معماری‌های Stateless نیز JWT ممکن است انتخاب مناسبی باشد.
 
پس بهتر است به جای اینکه بگوییم:
 
JWT همیشه بهتر از Session است.
 
بگوییم:
 
JWT و Session هرکدام کاربردها و مزایای خاص خود را دارند و انتخاب مناسب به معماری و نیازهای پروژه بستگی دارد.
 

JWT چه تفاوتی با Authentication و Authorization دارد؟

 
این سه مفهوم را نباید با یکدیگر اشتباه گرفت.
 

Authentication

 
یعنی:
 
«تو چه کسی هستی؟»
 
برای مثال، کاربر با نام کاربری و رمز عبور وارد سیستم می‌شود.
 

Authorization

 
یعنی:
 
«چه کاری اجازه داری انجام بدهی؟»
 
مثلاً کاربر معمولی اجازه حذف کاربران را ندارد، اما مدیر سیستم می‌تواند این کار را انجام دهد.
 

JWT

 
JWT یک فرمت Token است که می‌تواند در پیاده‌سازی سیستم‌های Authentication و Authorization مورد استفاده قرار گیرد.
 
پس:
 
Authentication → شناسایی کاربر
Authorization → تعیین سطح دسترسی
JWT → یکی از روش‌های انتقال اطلاعات قابل اعتبارسنجی
 
این تفاوت یکی از مهم‌ترین مفاهیمی است که هنگام یادگیری امنیت در برنامه‌نویسی باید بدانید.
 

برای یادگیری JWT از کجا شروع کنیم؟

 
اگر می‌خواهید JWT را به‌صورت اصولی یاد بگیرید، بهتر است مرحله‌به‌مرحله پیش بروید:
 

مرحله اول: HTTP را یاد بگیرید

 
با مفاهیمی مانند:
 
Request
Response
Header
Cookie
Status Code
 
آشنا شوید.
 

مرحله دوم: API را یاد بگیرید

 
مفاهیمی مانند REST API، Endpoint و HTTP Methods را یاد بگیرید.
 

مرحله سوم: Authentication و Authorization

 
تفاوت این دو مفهوم را به‌خوبی درک کنید.
 

مرحله چهارم: Token

 
با مفهوم Access Token، Refresh Token و Bearer Token آشنا شوید.
 

مرحله پنجم: JWT

 
ساختار Header، Payload و Signature را یاد بگیرید.
 

مرحله ششم: پیاده‌سازی عملی

 
JWT را با تکنولوژی‌هایی مانند:
 
JavaScript / Node.js
C#
ASP.NET Core
Python
PHP
 
در یک پروژه واقعی پیاده‌سازی کنید.
 

مرحله هفتم: امنیت

 
در نهایت درباره موضوعاتی مانند:
 
Token Expiration
HTTPS
XSS
CSRF
Refresh Token
Token Revocation
 
مطالعه کنید.
 

جمع‌بندی؛ JWT چیست؟

 
🎯 JWT یا JSON Web Token یک فرمت استاندارد برای انتقال اطلاعات به شکل یک توکن قابل اعتبارسنجی است که می‌تواند در سیستم‌های Authentication و Authorization مورد استفاده قرار گیرد.
 
JWT معمولاً از سه بخش تشکیل می‌شود:
 
Header.Payload.Signature
 
با JWT می‌توان در بسیاری از معماری‌های مدرن، به‌خصوص APIها و سیستم‌های Stateless، درخواست‌های کاربران را اعتبارسنجی کرد.
 
اما یک نکته را همیشه به خاطر داشته باشید:
 
🔐 JWT به‌خودی‌خود سیستم امنیتی کامل نیست؛ امنیت آن به نحوه طراحی، پیاده‌سازی و مدیریت Tokenها بستگی دارد.
 
اگر می‌خواهید در مسیر برنامه‌نویسی حرفه‌ای حرکت کنید، یادگیری مفاهیمی مانند JWT، Authentication، Authorization، API و امنیت وب به شما کمک می‌کند ساختار واقعی برنامه‌های مدرن را بهتر درک کنید.
 
در فرایانه تلاش می‌کنیم مفاهیم برنامه‌نویسی و فناوری را به زبان ساده، کاربردی و قابل فهم آموزش دهیم تا یادگیری برنامه‌نویسی برای علاقه‌مندان آسان‌تر و عملی‌تر باشد. 💚
JWT؛ کلید احراز هویت امن