JWT چیست؟ توضیح دو خطی و مرور تخصصی
اگر بخواهیم JWT را فقط در دو خط توضیح دهیم:
JWT یا JSON Web Token یک استاندارد فشرده و خودکفا برای انتقال امن اطلاعات بین دو سیستم است که عمدتاً برای احراز هویت و کنترل دسترسی استفاده میشود.
در عمل، یک رشته متنی امضاشده شامل اطلاعات کاربر است که سرور میتواند بدون نگهداشتن نشست یا Session آن را تأیید کند.
JWT دقیقاً چیست؟
JWT مخفف JSON Web Token است و طبق استاندارد RFC 7519 تعریف شده است. این توکن یک قالب باز و استاندارد برای انتقال امن ادعاها (Claims) بین دو طرف است. برخلاف نشستهای سنتی سمت سرور، JWT اطلاعات لازم را داخل خودش حمل میکند و به همین دلیل به آن Self-Contained گفته میشود.
ویژگیهای کلیدی JWT عبارتاند از:
- فشرده بودن: به دلیل استفاده از قالب JSON و کدگذاری Base64URL، حجم کمی دارد.
- خودکفا بودن: تمام اطلاعات لازم برای تأیید هویت و مجوزها در خود توکن وجود دارد.
- امضادار بودن: توکن با یک کلید مخفی یا کلید خصوصی امضا میشود تا سرور بتواند صحت آن را بررسی کند.
- مستقل از سرور: برای اعتبارسنجی نیازی به پایگاه داده نشست یا حافظه مشترک سرور نیست.
ساختار یک JWT
یک JWT از سه بخش اصلی تشکیل شده که با نقطه . از هم جدا میشوند:
header.payload.signature
نمونه یک JWT واقعی:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaSBSZXphaWUiLCJpYXQiOjE1MTYyMzkwMjJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
1. Header یا سرآیند
این بخش شامل اطلاعات الگوریتم امضا و نوع توکن است:
{
"alg": "HS256",
"typ": "JWT"
}
2. Payload یا بدنه
این بخش شامل ادعاها یا Claims است؛ یعنی اطلاعات کاربر و متادیتای توکن:
{
"sub": "1234567890",
"name": "Ali Rezaei",
"role": "admin",
"iat": 1516239022,
"exp": 1516242622
}
3. Signature یا امضا
بخش سوم با استفاده از الگوریتم مشخصشده در Header و یک کلید مخفی تولید میشود:
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
این امضا به سرور اجازه میدهد تشخیص دهد که آیا توکن پس از صدور تغییر کرده است یا نه.
JWT چگونه کار میکند؟
فرایند استفاده از JWT در یک سیستم احراز هویت معمولاً به این صورت است:
- کاربر نام کاربری و رمز عبور خود را ارسال میکند.
- سرور اطلاعات کاربر را تأیید میکند.
- سرور یک JWT حاوی اطلاعات کاربر و زمان انقضا میسازد و آن را برمیگرداند.
- کلاینت توکن را در حافظه یا حافظه محلی ذخیره میکند.
- در درخواستهای بعدی، کلاینت توکن را در هدر
Authorizationارسال میکند:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
- سرور توکن را با کلید مخفی یا کلید عمومی بررسی میکند و در صورت معتبر بودن، به درخواست پاسخ میدهد.
کاربردهای رایج JWT
- احراز هویت (Authentication): پس از ورود کاربر، JWT به عنوان مدرک هویت او استفاده میشود.
- کنترل دسترسی (Authorization): نقشها و سطح دسترسی کاربر میتواند در Payload قرار گیرد.
- تبادل اطلاعات: بین سرویسها یا میکروسرویسها میتوان اطلاعات را به صورت امن و امضاشده منتقل کرد.
- Single Sign-On یا SSO: در سیستمهایی که کاربر باید به چند سرویس مختلف دسترسی داشته باشد.
- ارتباط بین میکروسرویسها: برای انتقال هویت کاربر یا اطلاعات زمینهای بین سرویسهای داخلی.
مزایا و معایب JWT
مزایا
- بدون نیاز به Session: سرور نیازی به ذخیرهسازی نشست ندارد و میتواند به راحتی مقیاسپذیر باشد.
- قابل استفاده در دامنههای مختلف: مناسب برای معماریهای توزیعشده و میکروسرویسی.
- سازگار با موبایل و وب: به سادگی در هدر HTTP منتقل میشود.
- امنیت در انتقال داده: با امضای دیجیتال از دستکاری توکن جلوگیری میشود.
معایب
- افزایش حجم درخواست: چون توکن در هر درخواست ارسال میشود، ممکن است حجم ترافیک افزایش یابد.
- دشواری در ابطال توکن: پس از صدور، تا زمان انقضا نمیتوان به راحتی آن را باطل کرد مگر با استفاده از لیست سیاه یا Refresh Token.
- خطر فاش شدن اطلاعات: Payload فقط کدگذاری شده است، نه رمزنگاری؛ بنابراین اطلاعات حساس نباید در آن قرار گیرد.
- وابستگی به مدیریت صحیح کلید: اگر کلید امضا لو برود، امنیت کل سیستم به خطر میافتد.
نکات امنیتی مهم در استفاده از JWT
- همیشه از HTTPS استفاده کنید تا توکن در مسیر انتقال سرقت نشود.
- زمان انقضای کوتاه برای Access Token تعیین کنید.
- از Refresh Token برای دریافت دوباره Access Token استفاده کنید.
- اطلاعات حساس مانند رمز عبور یا شماره کارت بانکی را در Payload قرار ندهید.
- از الگوریتمهای قوی مانند HS256 یا RS256 استفاده کنید و الگوریتم
noneرا غیرفعال کنید. - کلید مخفی را در محیط سرور نگهداری کنید و هرگز آن را در کلاینت قرار ندهید.
- ورودی توکن را همیشه با استفاده از کتابخانه معتبر اعتبارسنجی کنید.
مثال عملی در Node.js
برای ساخت و بررسی JWT در Node.js میتوانید از کتابخانه jsonwebtoken استفاده کنید:
import jwt from 'jsonwebtoken';
const payload = {
userId: 123,
role: 'admin'
};
const secret = 'my-secret-key';
// ساخت توکن با زمان انقضای یک ساعت
const token = jwt.sign(payload, secret, { expiresIn: '1h' });
console.log('Token:', token);
// بررسی و استخراج اطلاعات توکن
try {
const decoded = jwt.verify(token, secret);
console.log('Decoded:', decoded);
} catch (error) {
console.error('Invalid token:', error.message);
}
خروجی نمونه:
Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEyMywicm9sZSI6ImFkbWluIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1MTYyNDI2MjJ9.7xY...
Decoded: { userId: 123, role: 'admin', iat: 1516239022, exp: 1516242622 }
جمعبندی
JWT یک راهحل مدرن و پرکاربرد برای احراز هویت و انتقال امن اطلاعات است که با ساختار ساده و امضای دیجیتال، نیاز به نشست سمت سرور را از بین میبرد. با این حال، استفاده صحیح از آن نیازمند رعایت اصول امنیتی مانند استفاده از HTTPS، زمان انقضای کوتاه و مدیریت درست کلیدهاست. اگر معماری شما توزیعشده است یا به دنبال راهکاری بدون Session هستید، JWT یکی از گزینههای اصلی و قابل اتکا محسوب میشود.