مشخصات مقاله
-
637
-
0.0
-
5031
-
0
-
0
مقدمهای بر JWT (JSON Web Tokens)
مقدمهای بر JWT (JSON Web Tokens)
JWT چیست؟
JWT یک استاندارد باز (RFC 7519) است که جهت انتقال امن اطلاعات میان طرفین و بهصورت یک شیء JSON راه امن و جامعی را تعریف میکند. صحت این اطلاعات قابلتأیید بوده و میتوان به آنها اعتماد کرد چرا که آنها از نظر دیجیتالی دارای امضا هستند. JWT ها را میتوان به کمک RSA یا ECDSA و با استفاده از یک کلید خصوصی/عمومی یا یک کلید محرمانه (با الگوریتم HMAC) امضا کرد.
هرچند که JWT ها را میتوان بهگونهای رمزگذاری کرد که بتوان محرمانگی را میان طرفین برقرار کرد اما ما تمرکز خود را بر روی توکن های امضاشده قرار میدهیم. توکن های امضاشده میتوانند درستی ادعاهای موجود در خود را اثبات کنند؛ این در حالی است که توکن های رمزگذاری شده این ادعاها را از طرفین مخفی میکنند. پس از آنکه توکن ها با استفاده از جفت کلیدهای اختصاصی/عمومی امضا میشوند، این امضا نیز گواهی میدهد که کسی غیر از دارندهی کلید اختصاصی آن را امضا نکرده است.
در چه مواقعی باید از JWT ها استفاده کرد؟
برخی از کاربردهای JWT را میتوانید در زیر مشاهده کنید:
- اختیاردهی (authorization): این زمینه رایجترین کاربرد JWT ها است. هر درخواستی که پس از وارد شدن کاربر داده میشود درون خود یک JWT را جای داده است و از این طریق کاربر میتواند به مسیرها، سرویسها و منابعی که از طرف این توکن مجاز اعلام شدهاند دسترسی پیدا کند. Single Sign On امکانی است که امروزه بهطور گستردهای از JWT بهره میگیرد که دلیل آن کوچک بودن سربار آن و آسانی استفاده از آن میان دامنههای مختلف است.
- تبادل اطلاعات: با کمک JWT ها میتوان میان طرفین به انتقال امن اطلاعات پرداخت. با توجه به اینکه JWT ها را میتوان مثلاً از طریق جفت کلید عمومی/اختصاصی امضا کرد، کاربر از بابت هویت فرستنده میتواند هیچ نگرانیای نداشته باشد. علاوه بر این با توجه به اینکه این امضا با استفاده از هدر و payload محاسبه میشود؛ در صورت وجود تحریف میتوانید متوجه وجود آن شوید.
ساختار JWT به چه صورت است؟
JWT ها در شکل متراکم خود متشکل از 3 بخش هستند که با نقطه (.) از یکدیگر جدا شدهاند:
- هدر (header)
- payload
- امضا (signature)
بنابراین یک JWT نوعی به شکل زیر در میآید:
xxxxx.yyyyy.zzzzz
حالا بیاید بهصورت جداگانه به هر بخش بپردازیم.
هدر
این بخش معمولاً متشکل از دو بخشِ نوع توکن و الگوریتم درهم سازی (hashing) است که در اینجا نوع توکن JWT و الگوریتم درهم سازی نیز HMAC SHA256 یا RSA است.
برای مثال:
{
"alg": "HS256",
"typ": "JWT"
{
سپس بهصورت Base64Url کدگذاری میشود تا بخش اول JWT را شکل دهد.
payload
بخش دوم توکن payload است که حاوی ادعاها و درخواستها است. این درخواستها دستوراتی در رابطه با یک نهاد (عموماً کاربر) و اطلاعات اضافی هستند. درخواستها ه سه دسته تقسیم میشوند: درخواستهای ثبت شده، عمومی و خصوصی.
- درخواستهای ثبت شده: این درخواستها، درخواستهای از پیش تعریفشدهای هستند که الزامی نیستند، اما جهت ارائهی مجموعهای از درخواستهای مفید و دارای قابلیت انتقال اطلاعات توصیه شدهاند. از جملهی آنها میتوان به iss (صادرکننده)، exp (زمان انقضا)، sub (موضوع)، aud (حضار) و ... اشاره کرد.
توجه داشته باشید که اسم درخواستها تنها از سه حرف تشکیل شدهاند، چرا که JWT باید فشرده باشد. - درخواستهای عمومی: این درخواستها را میتوان از طریق درخواستهایی که از JWT ها استفاده میکنند، تعریف کرد. اما برای آن که از تلاقی بین آنها جلوگیری شود، باید آنها را در IANA JSON Web Token Registry تعریف کرد یا اینکه آنها را بهصورت یک URI تعریف کرد؛ بهگونهای که این URI شامل یک فضای نام مقاوم در برابر تلاقی باشد.
- درخواستهای خصوصی: این درخواستها، درخواستهایی اختصاصی هستند که از طریق آنها میتوان اطلاعات را بین طرفینی که بر سر استفاده از آنها با یکدیگر توافق کردهاند و جزء درخواستهای عمومی یا ثبت شده نیستند، به اشتراک گذاشت.
در زیر یک payload نمونه را مشاهده میکنید:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
بنابراین در اینجا payload ،Base64Url است که بهگونهای کدگذاری شده است که میتواند بخش دوم JWT را ایجاد کند.
حتماً توجه داشته باشید که همهی افراد میتوانند این اطلاعات را در توکن های امضا شده بخوانند. هرچند که این اطلاعات در برابر تحریف مقاوم باشند. اطلاعات محرمانهی خود را بههیچوجه داخل عناصر هدر یا payload نگذارید، مگر آن که این اطلاعات رمزگذاری شده باشند.
امضا
برای آن که بتوانید بخش امضا را ایجاد کنید، باید هدر رمزگذاری شده، payload رمزگذاری شده، اطلاعات سری و الگوریتم مشخصشده در هدر را بگیرید و آن را امضا کنید.
برای مثال اگر میخواهید از الگوریتم HMAC SHA256 استفاده کنید، امضا بهصورت زیر ایجاد میشود:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
این امضا در تأیید عدم تغییر پیام در امتداد مسیر کاربرد دارد و اگر توکن ها همراه با یک کلید خصوصی امضا شده باشند، در این صورت این امضا میتواند هویت واقعی فرستندهی JWT را تأیید کند.
ترکیب موارد بالا در کنار یکدیگر
خروجی نهایی سه رشتهی Base64-URL است که با نقطههایی از یکدیگر جدا شدهاند و میتوان آنها را بهراحتی در محیطهای HTML و HTTP عبور داد. در عین حال این رشتهها در مقایسه با استانداردهای مبتنی بر XML مثل SAML فشردهتر هستند.
در ادامه یک JWT را مشاهده میکنید که دارای هدر و payload رمزگذاری شده است و همراه با اطلاعات سری امضا شده است.
اگر میخواهید که با JWT بازی کنید و تمامی این مفاهیم را در عمل مشاهده کنید، میتوانید برای کدبرداری، تأیید و تولید JWT ها از اشکالیاب jwt.io استفاده کنید.
شیوهی کارکرد JWT ها به چه صورت است؟
طی احراز هویت پس از آن که کاربر با موفقیت با استفاده از اطلاعات محرمانهی خود وارد حساب خود میشود، یک JWT برگشت داده میشود. با توجه به این که توکن ها اطلاعات محرمانهای هستند، باید بهشدت مراقب مشکلات امنیتی باشیم.
هر زمان که کاربر بخواهد به یک مسیر یا منبع حفاظتشده دسترسی پیدا کند، عامل کاربر باید JWT را عموماً در هدر Authorization و با استفاده از طرح Bearer ارسال کند.
محتوای هدر چیزی شبیه به کد زیر است:
Authorization: Bearer < token >
- برنامه یا کلاینت به سرور اختیاردهی درخواست اختیار را صادر میکند. این کار از طریق یکی از جریانهای متفاوت اختیاردهی انجام میشود. مثلاً مسیر یک برنامهی اینترنتی موافق با OpenID Connect از نقطهی انتهایی /oauth/authorize و با استفاده از جریان کد اختیاردهی میگذرد.
- پس از اختیاردهی، سرور اختیاردهی یک توکن دسترسی را به برنامه برگشت میدهد.
- برنامه برای دسترسی به یک منبع حفاظتشده (مانند یک API) از این توکن دسترسی استفاده میکند.
توجه داشته باشید که در توکن های امضا شده، تمامی اطلاعات موجود در این توکن در دسترس کاربران یا طرفین دیگر قرار دارند. هرچند که نمیتوانند این اطلاعات را تغییر دهند. این یعنی شما بهتر است که اطلاعات سری خود را داخل این توکن قرار ندهید.
چرا اصلاً باید از JWT ها استفاده کنیم؟
بیایید مزایای JWT ها را با SWT و SAML مقایسه کنیم.
با توجه به این که JSON کوتاهتر از XML است، پس از کدگذاری شدن اندازهی آن نیز کوچکتر میشود. این امر باعث میشود JWT از SAML فشردهتر شود و JWT به گزینهی مناسبی تبدیل شود که بتوان آن را در محیطهای HTML و HTTP عبور داد.
از نظر امنیت SWT را تنها میتوان بهصورت متقارن و با استفاده از یک سری اطلاعات محرمانهی مشترک و از طریق الگوریتم HAMC امضا کرد. با این حال توکن های JWT و SAML تنها میتوانند از یک جفت کلید عمومی / خصوصی و به شکل گواهی X.509 استفاده کنند تا درنهایت کار امضا کردن انجام شود. امضا کردن XML به کمک امضای دیجیتال XML بدون ارائهی حفرههای امنیتی مبهم کار بسیار سختی است و JSON این کار را بسیار سادهتر انجام میدهد.
تجزیهکنندههای JSON در اغلب زبانهای برنامهنویسی رایج هستند، چرا که آنها ارتباط مستقیمی با اشیاء دارند. در مقابل XML بین سند و شیء دارای ارتباطی ذاتی نیست که این امر باعث میشود کار با JWT نسبت به SAML آسانتر شود.
از نظر کاربرد، JWT در مقیاس اینترنت کاربرد دارند که این امر بیانگر سهولت پردازش سمت کلاینت JWT در پلتفرمهای مختلف بهویژه تلفنهای همراه است.
در مقابل
مقایسهی طول JWT رمزگذاری شده با یک SAML رمزگذاری شده
اگر میخواهید در رابطه با JWT ها اطلاعات بیشتری کسب کنید و حتی جهت احراز هویت در برنامههای خود از آنها استفاده کنید، به لینک JSON Web Token landing page در وبسایت Auth0 مراجعه کنید.