JWT چیست؟ چه زمانی از JSON Web Token استفاده کنیم؟

JWT چیست؟ چه زمانی از JSON Web Token استفاده کنیم؟

آموزشی
19 اسفند 1403

برای درک بهتر این مطلب، پیشنهاد میشه که مقالات زیر رو مطالعه کنید:

 

فک کنید یک برنامه دارید که با معماری REST طراحی شده که توی این مثال گیک باز رو مدنظر میگیریم. زمانی که با API هایی از جنس رست به سمت سرور Request ای ارسال میشه به دلیل ماهیت Satateless بودن RESTful API ها، هر درخواست کاملا مستقل از درخواست های دیگه است و سرور هیچ اطلاعی از درخواست های قبلی نداره، در واقع اطلاعات وضعیت درخواست های قبلی در سمت سرور ذخیره نشده پس در هر درخواست باید حاوی تمامی اطلاعات لازم برای درک سرور باشه.

حالا با شرایط بالا بدون اینکه بدون اینکه وابسته به سشن برای احراز هویت باشیم و دیگه مجبور نباشیم برای کاربر در سمت سرور یک سشن ذخیره کنیم، پس چطوری بعد از اینکه کاربر لاگین کرد توی درخواست های بعدیش بفهمیم این کاربر، همون کاربری است که یکم قبل تر لاگین کرده؟ به جواب این سوال در ادامه مقاله میرسیم. 

 

JWT چیست؟

JSON Web Token یا JWT یک روش استاندارد برای انتقال امن اطلاعات بین دو سیستم (معمولا بین کلاینت و سرور) در قالب JSON است. ساختار JWT به سه بخش اصلی تقسیم می شود:

  • - Header
  • - Payload
  • - Signature

این سه بخش با نقطه (.) از هم جدا میشن که نتیجه ای به شکل زیر داره:

Header.Payload.Signature

یک نمونه واقعی شبیه مورد زیر است:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30

 

ساختار JWT

همون طور که بالاتر گفته شد ساختار JWT سه بخش اصلی داره که در تصویر زیر به طور کلی نمایش داده شده:

ساختار JWT یا JSON Web Token

 

بخش Header

این بخش شامل اطلاعاتی درباره توکن است مثل نوع توکن یا الگوریتمی که قراره برای امضای دیجیتال استفاده بشه که اصطلاحا signing algorithm میگن. در مثال زیر نوع توکن JWT است و الگوریتم HS256 است (البته انتخاب های دیگه ای هم مثل HS512 یا RS256 یا SHA256 و.. هم وجود داره):

{
    "alg": "HS256",
    "typ": "JWT"
}

نکته: دیتای بالا با base64url انکود میشن و نتیجه اون، بخش اول توکن رو میسازه:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

 

بخش Payload

تمام اطلاعاتی که قراره انتقال پیدا کنه در این بخش تعریف میشن به عنوان مثال:

{
    "sub": "1234567890",
    "name": "Saeed Amini",
    "admin": true,
    "iat": 1516239022,
    "exp": 1672531199
}

توجه:

  • - عنوان (sub یا subject): عنوان یا شناسه کاربر
  • - issued at (iat): زمان صدور توکن
  • - exp یا expiration: تاریخ انقضای توکن

نکته: بخش Payload پس از اینکه با base64url انکود شد، بخش دوم توکن رو میسازه:

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0

 

بخش Signature

این بخش که مهم ترین بخش هم است و از ترکیب Header و Payload انکود شده با base64url که با Secret ترکیب میشود که مثل کلید رمز است پس باید با دقت انتخاب شود. وقتی که انکود شده‌ی Header و Payload رو با Secret ترکیب شد، با الگوریتمی که در بخش Header انتخاب کردیم مقدار رو هش (hash) می کند به عنوان مثال با استفاده از الگوریتم HMAC SHA256 مقادیری که گفتیم رو هش می کنیم:

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

نکته: نتیجه بالا بخش سوم یا Signature رو تشکیل میده:

KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30

 

چرا کلید Secret در Signature مهم است؟

هر کسی میتونه بخش Header و Payload‌ که انکود کردیم رو دیکود کنه و مقادیر اولیه رو بدست بیاره. به همین دلیله که گفته میشه Signature امنیت توکن رو تضمین میکنه.

حالا فرض کنید که کلید Secret شما دزدیده شده (که به هیچ عنوان نباید اجازه همچین اتفاقی رو بدید)، حالا کسی که به این کلید دسترسی داره میتونه مقادیر Header و Payload رو انکود کنه و با کلید Secret ادغام کنه و نتیجه نهایی رو هش کنه و هر چقدر که بخواد توکن تولید کنه که این مسئله فاجعه به وجود میاره.

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

 

مزایای استفاده از Json Web Token

JWT با مزایای خیلی زیادی که داره در بسیاری از برنامه ها، مخصوصا برنامه هایی که مبتنی بر REST هستن خیلی پرکاربرد است و از مهم ترین مزایای اون شامل:

 

احراز هویت Stateless

در احراز هویت با JWT نیازی به ذخیره سشن در سمت سرور ندارید. برای اعتبار سنجی سشن، اون session id ای که در کوکی برای کاربر لاگین شده ذخیره شده با سشن ای که در سرور ذخیره شده مقایسه میشه ولی JWT حاوی تمامی اطلاعات لازم برای احراز هویت است نیازی به ذخیره سازی در سرور ندارد و یه جورایی میشه گفت خودش میتونه خودش رو اعتبار سنجی کنه که این خیلی نکته مثبتی است.

 

پشتیبانی از Cross Platform

JWT در احراز هویت شما رو محدود به استفاده از تکنولوژی خاصی نمی کنه و میتونید با زبان های برنامه نویسی مختلفی مثل python، javascript،java و.. از اون استفاده کنید.

 

انقضای داخلی

در زمان ساخت توکن JWT، تاریخ انقضا تعریف شده پس به صورت built-in تاریخ انقضا داره و این باعث میشه حتی اگر توکن دزدیده بشه تا ابد قابل استفاده نباشه و بعد از زمان تعیین شده توکن منقضی میشه.

 

امنیت

JWT به همراه کلید امنی با استفاده از الگوریتم های قوی و با امنیت بالا هش میشه و تا زمانی که کلید Secret امنی انتخاب کنید و به درستی از اون محافظت کنید مشکلی نخواهید داشت.

 

فشرده و سریع

کوچیک بودن حجم JWT باعث میشه که به راحتی در header درخواست های HTTP قابل استفاده باشه که باعث میشه اون رو برای API ها ایده ال کنه و روش اضافه کردن توکن به HTTP header به صورت زیر است:

Authorization: Bearer <token>

 

چه زمانی از JWT استفاده کنیم؟

Json Web Token برای سیستم های بزرگ و مقیاس پذیر (مثل معماری میکروسرویس ها) و برنامه هایی که ارتباط سرویس ها با API یا RESTful API ها است به خاطر ماهیت Stateless ای که داره میتونه یک گزینه عالی باشه.

در اپلیکیشن هایی تک صفحه ای (SPA) یا SSR و.. که ارتباط با سمت بک اند از طریق API است JWT یک انتخاب ایده ال و امن برای احراز هویت است.

به دلیل ماهیت Cross platform سیستم هایی که روی پلتفرم های مختلف برنامه دارن (مثلا هم وبسایت و هم برنامه موبایل دارن) و میخوان سیستم احراز هویت یکپارچه داشته باشد قطعا JWT یک انتخاب خیلی مناسب برای چنین حالتی است.

 

نتیجه گیری

Json Web Token روشی امن و مقیاس پذیر برای احراز هویت در اختیار توسعه دهنده قرار میده که میتونه توی برنامه های مختلف مثل وب اپلیکیشن ها و برنامه های موبایل و.. استفاده بشه.

با زبان های برنامه نویسی مختلفی میتوان با JWT کار کرد که یکی از محبوب ترین اون ها پایتون است. اگر با python آشنایی ندارید و درکی از پایتون چیست؟ ندارید میتونید آموزش پایتون رو به صورت رایگان ببینید.

author-avatar
سعید امینی
نویسنده مقاله

الان بیشتر از پنج ساله که مشغول برنامه نویسی وب هستم و در طول این مدت کلی چالش رو پشت سر گذاشتم و عاشق اینم که هر چیزی رو که در این مدت یاد گرفتم رو به بقیه هم یاد بدم، الانم در بستر سایت گیک باز دارم دانشم رو با بقیه تقسیم میکنم :)

نظرات

هنوز نظری وجود ندارد! شما اولین نفر باشید...