Hamid Shoja
Hamid Shoja
خواندن ۵ دقیقه·۵ ماه پیش

کی باید از session و کی از JWT برای authentication استفاده کنیم ؟

درود به دوستان عزیز

بعد مدت ها گفتم پست داشته باشم
امروز میخام درباره authentication و JSON Web Tokens یا JWT ها حرف بزنیم. مکانیزم هر کدومو رو بررسی میکنیم و مزایا و معایبشون رو نگاه کنیم.و آخرش بهیمم کی از کدوم باید استفاده کنیم.


اگر علاقمندی این مقاله رو در قالب ویدیو ببینی تو یوتوب میتونی تماشا کنی

بررسی Session

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

اول بیا ببینیم authentication مبتنی بر session چجوری کار می‌کنه:


  1. کاربر اطلاعات ورودش رو می‌فرسته به سرور
  2. سرور این اطلاعات رو چک می‌کنه
  3. اگه درست باشن، یه session جدید می‌سازه
  4. سرور اطلاعات session رو ذخیره می‌کنه، معمولا تو database یا تو حافظه موقت مثل Redis
  5. این اطلاعات می‌تونه شامل ID کاربر، زمان انقضای session و چیزای دیگه باشه
  6. سرور یه جواب می‌فرسته با یه ID session منحصر به فرد، معمولا به شکل cookie
  7. تو درخواست‌های بعدی، کلاینت خودکار این ID session رو با هر درخواست می‌فرسته
  8. سرور این ID رو می‌گیره، اطلاعات session مربوطه رو پیدا می‌کنه و ازش برای authentication و پردازش درخواست استفاده می‌کنه
نکته مهم اینه که تو authentication مبتنی بر session، سرور مسئول ساخت و ذخیره اطلاعات session هست. بعدش از ID session به عنوان کلید استفاده می‌کنه تا این اطلاعات رو تو درخواست‌های بعدی بازیابی کنه.

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

ولی تو یه سیستم توزیع شده که برنامه‌ت رو چندتا سرور اجرا میشه، همه این سرورا باید به اطلاعات session دسترسی داشته باشن. معمولا اینو با یه session store مرکزی مثل Redis یا یه Distrbiued sql database انجام میدن. این روش خوب کار می‌کنه ولی یه کم پیچیدگی اضافه می‌کنه و ممکنه هر درخواست رو کند کنه چون سرور باید جداگانه بره سراغ session store.

بررسی JWT:

جیسون وب توکن یا JWT یه نوع توکنه که به صورت JSON فرمت شده و شامل اطلاعات کاربره.

حالا بیا ببینیم authentication مبتنی بر JWT جات چجوری کار می‌کنه:


  1. کاربر اطلاعات ورودش رو می‌فرسته به سرور
  2. سرور این اطلاعات رو چک می‌کنه
  3. اگه درست باشن، یه JWT می‌سازه
  4. سرور JWT رو با یه کلید مخفی secret key امضا می‌کنه. این امضا از دستکاری توکن token integrity جلوگیری می‌کنه
  5. سرور JWT رو برمی‌گردونه به کلاینت، معمولا تو response body
  6. کلاینت JWT رو ذخیره می‌کنه، معمولا تو local storage یا cookie
  7. تو درخواست‌های بعدی، کلاینت JWT رو تو header درخواست می‌فرسته
  8. سرور امضای JWT رو چک می‌کنه. اگه معتبر باشه، به اطلاعات داخل توکن اعتماد می‌کنه و ازش برای authentication و authorization استفاده می‌کنه
تفاوت مهم اینه که با JWT ها، سرور هیچ وضعیت session رو ذخیره نمی‌کنه. همه اطلاعات لازم داخل خود توکن هست که روی کلاینت ذخیره میشه. این باعث میشه JWT ها stateless باشن.


امضای JWT‌ها

برای امضای JWT‌ها چند تا الگوریتم داریم که HMAC، RSA و ECDSA از معروف‌ترین‌هاشونن.

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


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


انتخاب الگوریتم امضا بستگی به نیازهای امنیتی و معماری سیستمت داره. اگه یه برنامه یکپارچه داری یا به همه سرویس‌های سیستمت اعتماد داری، HMAC کافیه. ولی اگه معماری microservices داری یا می‌خوای JWT‌ها رو با سرویس‌های شخص ثالث غیرقابل اعتماد به اشتراک بذاری، RSA یا ECDSA راه حل امن‌تری ارائه می‌دن.



رفرش توکن

یکی از چالش‌های JWT‌ها، مدیریت انقضای توکن‌هاست. اگه یه توکن دزدیده بشه، تا وقتی منقضی نشده قابل استفاده‌س. برای کم کردن این خطر، می‌تونی از refresh token‌ها در کنار access token‌های کوتاه‌مدت استفاده کنی.


اکسس تون access token همون JWT اصلیه که برای authentication تو هر درخواست استفاده می‌شه و معمولا حدود 15 دقیقه اعتبار داره. refresh token از طرف دیگه خیلی طولانی‌تر اعتبار داره، شاید چند روز یا چند هفته.

وقتی access token منقضی می‌شه، به جای اینکه از کاربر بخوای دوباره لاگین کنه، کلاینت می‌تونه درخواست refresh token رو به یه endpoint خاص تو سرور بفرسته. سرور چک می‌کنه ببینه refresh token معتبره و باطل نشده، اگه همه چی درست باشه یه access token جدید صادر می‌کنه. این فرایند پشت صحنه اتفاق می‌افته و کاربر متوجه نمی‌شه.

این روش بین امنیت و تجربه کاربری تعادل ایجاد می‌کنه. access token کوتاه‌مدت خطر سوءاستفاده رو کم می‌کنه، در حالی که refresh token طولانی‌مدت اجازه می‌ده کاربرا برای مدت طولانی لاگین بمونن بدون اینکه مجبور باشن مدام وارد سیستم بشن.

مهمه بدونی که درخواست refresh token فقط وقتی فرستاده می‌شه که access token منقضی شده باشه، نه تو هر درخواست. access token تو هر درخواستی که نیاز به authentication داره فرستاده می‌شه.


پس کی باید از authentication مبتنی بر session استفاده کنی و کی JWT بهتره؟

کی session خوبه وقتی:

- می‌خوای بتونی فوراً session‌ها رو باطل کنی

- قبلاً یه مخزن داده مرکزی برای کارای دیگه داری و می‌تونی ازش برای ذخیره session هم استفاده کنی

- می‌خوای داده‌های حساس رو روی سرور نگه داری که امنیت بیشتری داره

کیJWT‌ها گزینه خوبی هستن وقتی:

- به یه معماری stateless نیاز داری چون همه اطلاعات لازم تو خود توکن ذخیره می‌شن

- می‌خوای برنامه‌ت رو راحت‌تر روی چند سرور مقیاس‌پذیر کنی

- نیاز داری اطلاعات authentication رو با سرویس‌های دیگه به اشتراک بذاری، مثلاً تو معماری microservices


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


اگه از مقاله خوشت اومده، ممکنه مقالات بعدی هم برات جالب باشه پس فالو و لایک یادت نره

ضمنا سورس این مقاله bytebytego هست که محتوای خیلی خوبی تولید میکنه و میتونید سایتشو دنبال کنید و منم این مقاله رو که بنظرم خیلی مفید بود از روش ترجمه کردم


تا مقاله بعدی بدورد

حمید شجاع

jwtauthenticationjson web tokenتجربه کاربری
Write Clean Code and Make everyone happy
شاید از این پست‌ها خوشتان بیاید