حمزه قائم پناه
حمزه قائم پناه
خواندن ۳ دقیقه·۶ ماه پیش

همه چی درباره JWT

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

به یاد داشته باشیم که JWT یک توکن sign شده است نه رمزنگاری شده. پس اطلاعات حساس رو داخلش قرار ندیم.

در واقع JWT مخفف JSON Web Token است که یک استاندارد بازه که انتقال اطلاعات JSON، بین دو موجودیت رو امن می‌کنه.

یک JWT که sign شده، می‌تونه یکپارچگی اطلاعات داخلش رو ادعا کنه، درحالی‌که یک توکن encrypt شده، می‌تونه مخفی بودن اون اطلاعات رو ادعا کنه. امضای روی توکن امضا شده با public/private key گواهی می‌کنه که فقط کسی که کلید خصوصی رو داره، توکن رو امضا کرده.

در پروتوکل‌های stateless، چیزی در مورد درخواست قبلی نمی‌دونه و باید با هر درخواست خودت رو معرفی کنی. اینکه بخوای از session استفاده کنی و کاربر درخواست لاگین بده و بعد یک session id بگیره و با هر درخواست بعدیش بفرسته، راهکار مناسبی نیست، چون این داده session روی سرور ذخیره میشه و حافظه می‌گیره، مدیریت باید بکنیش و session های غیرفعال رو منقضی کنی. هربار باید چک کنی که session معتبر هست یا نه و این کار سربار داره.

اما JWT از session استفاده نمی‌کنه، سرور بجای ایجاد session، وقتی کاربر اطلاعات شناسایی شو می‌فرسته، یک JSON Web Token برمی‌گردونه، که باهاش همه کارهایی که نیاز به دسترسی داره رو می‌تونی انجام بدی.

مشابه کارت هتله که بعد از رجیستر کردن بهت میدن و باهاش به اتاقت و کافه و استخر و بقیه بخش‌ها دسترسی داری اما به بقیه اتاق‌ها و بخش‌های مدیریتی دسترسی نداری و تاریخ انقضا هم داره.

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

  • اول Authorization: استفاده مرسومش برای اعتبارسنجیه، بعد از لاگین، همه درخواست‌ها با خودشون JWT رو دارن و به کاربر بنا به دسترسی‌هاش، اجازه دسترسی رو میده.
  • دوم انتقال اطلاعات: انتقال امن اطلاعات بین بخش‌ها رو تسهیل می‌کنه. ارسال کننده JWT با امضایی که انجام میده، می‌تونه مشخص بشه، به طور مثال با استفاده از کلید خصوصی و عمومی. همینطور، به دلیل اینکه امضا براساس header و payload محاسبه میشه، می‌تونم تایید کنیم که اطلاعات تغییری داده نشده.

مزیت‌های JWT

  • سبک بودنش. از XML encode شده، فضای کمتری نیاز داره.
  • به session نیازی نداره.
  • به طور داخلی expiration داره.
  • به cookie نیازی نداره.

ساختار JWT

سه بخش اصلی داره که به این شکله:

<<header>>.<<payload>>.<<signature>>

بخش Header:

معمولا دو بخش توی header هست، نوع توکن (JWT) و الگوریتمی که برای امضا شدنش استفاده شده (RSA, HMAC).

بخش Payload:

این بخش شامل اطلاعاتی که ادعا میشه از سرور اومده. می‌تونه اطلاعات مرتبط با یک موجودیت یا هر اطلاعاتی باشه. ما سه نوع claim داریم که در این قسمت می‌تونیم استفاده کنیم:

  • نوع Registered Claims: از قبل تعریف شده هستن، اجباری نیستن اما امنیت رو بالا می‌برن.
    iss: issuer
    sub: subject
    exp: expiration time
    nbf: not before
    iat: issued at
  • نوع Public Claims: چیزایی که خود کاربر تعریف می‌کنه و متناسب با اپ هست.
  • نوع Private Claims: مواردی که برای اشتراک اطلاعات بین بخش‌هاس و روش توافق شده و اسامیش توسط توافق طرفین انتخاب شده.

بخش SIgnature:

برای تولید امضا، لازمه که encoded header و encoded payload و secret رو با الگوریتمی که در header مشخص کردیم sign کنیم.

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

encode64({ &quotalg&quot: &quotHS256&quot, &quottyp&quot: &quotJWT&quot }). encode64({ &quotsub&quot: &quot1234567890&quot, &quotname&quot: &quotJohn Doe&quot, &quotadmin&quot: true, &quotiat&quot: 1516239022 }). HMACSHA256( base64UrlEncode(header) + &quot.&quot + base64UrlEncode(payload), your-256-bit-secret )

آسیب‌پذیری‌های معمول JWT

  • دیتای توکن رو تغییر بده و الگوریتم رو none بزنه (انواع variation کلمه none).
  • کوتاه بودن shared secret برای اینکه سریع باشه، اما باعث میشه حملات brute force آسون‌تر بشه. طول shared secret HS256/384/512 ضروریه.
  • ممکنه اطلاعات payload رو تغییر بدی و به اندپویت بفرستی و در exception برگشتی امضا درست که انتظار داشته رو برگردونه!
  • از طریق پارامتر kid می‌تونه SQL Injection, Path traversal, command injection انجام بده.
  • دستکاری آدرس URL و الگوریتم به روش JWKS Injection/JWKS Spoofing

استانداردهای پیاده‌سازی Best Practices

  • نوع الگوریتم رو بررسی کنین که None نیاد.
  • ورودی‌های کریپتوگرافیک رو همیشه validate کنین.
  • از کلیدهای رمز قوی استفاده کنین.
jwt
مهندس نرم‌افزار و عاشق توسعه فردی - مهندس نرم‌افزار - اکس هم بنیان‌گذار و مدیرفنی و پرداکت استارتاپ کشمون
شاید از این پست‌ها خوشتان بیاید