یکی از بخشهای کلیدی در طراحی هر نرمافزاری، نحوهی پیادهسازی احراز هویت کاربرانشه.
در این مسیر، ابزارهایی مثل JWT و Session Token نقش مهمی دارن و خیلیها ازشون استفاده میکنن.اما قبل از اینکه وارد بحث اصلی بشیم، بیاید اول با هم ببینیم اصلاً این دوتا چی هستن و چه تفاوتی با هم دارن؟
فرض کنید وارد یک سایت میشید و با نام کاربری و رمز عبور لاگین میکنید.حالا سایت چطور باید توی صفحه های بعدی تشخیص بده که شما همون کاربر لاگین شده هستید؟ اینجاست که پای Token میاد وسط.
تعریف Session Token:
در این روش، سایت یه توکن تصادفی برای شما تولید میکنه و اون رو روی سرور خودش نگه میداره. توی مرورگر شما هم یه نسخه از اون ذخیره میشه(مثلا توی کوکی). بعد از اون هر بار که درخواستی میفرستید، مرورگر اون توکن رو همراه با درخواست شما ارسال میکنه، و سایت از طریق توکن ارسالی مرورگر تشخیص میده شما کی هستید
اما JWT :
JWT نوع خاصی از توکن هست که برای انتقال اطلاعات بین مرورگر و سرور به صورت امن استفاده میشه.وقتی کاربر لاگین میکنه سرور یک توکن JWT برای کاربر میسازه که توش اطلاعات شناسایی کاربر هست و اون رو به کاربر میده ،در واقع JWT مثل یک کارت شناسایی دیجیتال هست که تمام مشخصات شما روش نوشته شده و با یک مهر رسمی از طرف سرور تایید شده.کاربر در درخواست های بعدی خود که سمت سرور ارسال میکند JWT به سرور نشان داده میشود و سرور بدون اینکه به آرشیو مراجعه کنه،مطمئن میشه که کاربر شخص مورد نظر هست.
تفاوتش با session token چیه:
توکنهای Session معمولاً فقط یه شناسه (ID) هستن و اطلاعات رو سرور نگه میداره.
JWT خودش شامل اطلاعات کاربر و وضعیت هست و سرور لازم نیست اطلاعاتی ذخیره کنه (به این حالت میگن Stateless).

با گذشت زمان JWT وارد جریان اصلی احراز هویت و توسعه وب شدن و کم کم session token ها به دست فراموشی سپرده شدند.
اما در ادامه مسیر معلوم شد JWT ها جادویی نیستند و استفاده از اونا به جای session token ها میتونه یه کابوس امنیتی از نرم افزار شما درست کنه.
حالا بیایم کمی عمیق تر بشیم:
ما زمان احراز هویت دو حالت برایمان رخ میدهد:
حالت Stateful Auth(Session Token):
سرور اطلاعات توکن را در یک پایگاه داده ذخیره میکند
کاربر یک شناسه توکن تصادفی به عنوان کوکی دریافت میکند
هردرخواست که کاربر سمت سرور میفرستد، سرور با توجه به کوکی کاربر دنبال شناسه توکن میگردد تا کاربر را پیدا کند
اگر کاربر logout کند سرور توکن کاربر را از پایگاه داده حذف میکند
به این حالت stateful میگویند زیرا سرور تا زمان logout اطلاعات session را نگه میدارد.
حالت Stateless Auth(JWT):
سرور اطلاعات کاربر را در توکن JWT رمزنگاری و امضا میکند
هیچ اطلاعاتی راجب session ذخیره نمیشود
هر درخواست کاربر توکن JWT را نیز همراه خود دارد
سرور فقط امضای توکن را اعتبارسنجی میکند و نیازی به جستجوی اطلاعات در جایی ندارد
به این حالت stateless میگویند چون هیچ ذخیره سازی راجب session صورت نمیگیرد.
حالا بریم سراغ اصل مطلب،چه مشکلاتی به وجود می آید؟؟؟
1-امکان لغو توکن JWT وجود ندارد
توکن های JWT مستقله و شامل همه اطلاعات میشه. وقتی یک توکن JWT ساخته میشه تا وقتی تاریخ انقضاش نرسه معتبر باقی میمونه و نمیتونید حذف یا لغوش کنید این یعنی عملی مثل logout که نیاز به لغو توکن داره عملا وجود نداره.
حالا فرض کنید توکن شما دزدیده بشه؟! اون شخص میتونه تا زمان انقضای توکن داخل سیستم بمونه.
شما در Session token به راحتی میتونید با حذف اون توکن از پایگاه داده توکن رو لغو کنید
2-JWT ها بسیار پرحجم هستند
توکن های JWT در مقایسه با Session token ها که صرفا شناسه توکن رو ذخیره میکنند بسیار پرحجم تر هستند مخصوصا وقتی بخواهید اطلاعاتی مانند نقش ها ، دسترسی ها ، شناسه سازمان ها و ... را رمزگذاری کنید
اگر به هدر authorization امضا رو هم اضافه کنید حجم هردرخواست حدودا 800 بایت خواهد شد.این رو در هزاران درخواست API ضرب کنید میبیند که پهنای باند مصرفی افزایش و نرخ موفقیت حافظه کش(Cache Hit)کاهش پیدا میکند و در نتیجه سرعت کل سیستم افت پیدا میکنه.
3- نداشتن گردش توکن (Rotation) و دوره تنفس (Grace Period)
وقتی یک توکن دسترسی (Access token) یا توکن رفرش (Refresh token) صادر میشه برای افزایش امنیت بهتره که بعد از مدتی اون توکن رو با یک توکن جدید جایگزین کنیم(مثلا توکن دسترسی هر 15 دقیقه یکبار عوض بشه) به این کار میگن گردش توکن.
وقتی توکن رو عوض میکنیم، ممکنه چند لحظه طول بکشه تا همه سیستمها متوجه بشن که توکن قبلی دیگه معتبر نیست.
دوره تنفس یعنی یک بازه زمانی کوتاه که توکن قدیمی هنوز کمی اعتبار داره تا کاربر یا سیستم مشکلی نداشته باشه و بدون قطعی ادامه بده.
توکنهای JWT وقتی ساخته شدن، دیگه قابل تغییر نیستن.
یعنی اگه بخوای توکن رو «عوض» یا «بهروزرسانی» کنی، باید کلی تنظیمات پیچیده انجام بدی.
درسته که توکنهای رفرش (Refresh Token) برای این کار هستن، اما بیشتر برنامهنویسها:
درست ازش استفاده نمیکنن،
هر دو توکن رو توی localStorage ذخیره میکنن (که امن نیست)،
موارد خاص مثل ورود/خروج همزمان (parallel logout/login) را در نظر نمیگیرند.
اما توکنهای session این مشکل رو ندارن:
سرور میتونه راحت session ID رو عوض کنه،
حتی میتونه برای مدت کوتاهی هر دو session (قدیم و جدید) رو قبول کنه تا مشکلی پیش نیاد.
اما برای JWT باید کلی دردسر بکشی:
توکن دسترسی رو مثلاً هر ۱۵ دقیقه عوض کنی،
توکن رفرش رو هم هر بار که استفاده میکنی دوباره بسازی،
یه لیست سیاه درست کنی از توکنهای باطلشده،
و بعد هم دعا کنی همه چیز درست کار کنه!
گول جذابیت JWT رو نخورید!
JWT ابزار قدرتمندیه، اما نه برای هر سناریویی.هیچ تکنولوژی و ابزاری بدون عیب نیست.
قبل از استفاده، مزایا و معایبش رو کامل بسنجید و ببینید آیا مناسب پروژه شما هست یا نه.
امنیت هیچوقت نباید فدای سادگی بشه.
مخصوصاً وقتی صحبت از ورود، خروج و کنترل دسترسی کاربرهاست.
پس لطفاً دیگه از JWT بهجای Session Token استفاده نکنید!