سشن و توکن و کوکی

سلام و عرض احترام دارم خدمت دوستان عزیز

در این مقاله قصد دارم در خصوص روشهای احراز هویت توضیحاتی را در حد مقدماتی خدمتتان عرض کنم

احراز هویت کاربران
احراز هویت در نرم افزارهای کامپیوتری به فرایندی جهت شناسایی کاربران برای دسترسی به بخش های مختلف نرم افزار گفته می شود. 
طی این فرایند در صورت تصدیق و تطبیق اطلاعات کاربر با اطلاعات قبلی موجود در سیستم، مجوز دسترسی به بخش های مختلف نرم افزار که برای عموم مخفی است صادر می گردد و کاربر احراز شده از آن پس می تواند برای مدت زمان مشخصی یا بصورت مادام العمر به سیستم دسترسی داشته باشد.
مدت زمان دسترسی کاربر بعد از عملیات احراز هویت و همچنین سطح دسترسی کاربر احراز شده بستگی به سیاست های تنظیمی مدیر سیستم دارد . لازم به ذکر است که وسیله شناسایی و احراز هویت در سیستم های مختلف کامپیوتری ، متفاوت بوده ولی اغلب به شکل  رمز عبور ،  ترکیب نام کاربری و رمز عبور ، کارت مغناطیسی ، شناسه توکن و ... در اختیار کاربران قرار داده می شود تا کاربر بتواند با استفاده از آن به سیستم دسترسی داشته باشد.
- احراز هویت بطور کلی در 2 مرحله اصلی انجام می شود :
 Authentication  : به مجموعه از فرایندهایی گفته می شود که بوسیله آن کاربر شناسایی می شود که چه کسی هست .
Authorization   :  به مجموعه ای از فرایندها گفته می شود که بعد از مرحله شناسایی انجام می گیرد و سطوح دسترسی کاربر مشخص می شود.
 
همانطور که در تعاریف این  2 مرحله مشخص هست ، سیستم قبل از هر کاری ، برای احراز هویت کاربر ابتدا باید شخص را تشخیص دهد و بفهمد که این شخص چه کسی میباشد که برای اینکار ما معمولا فرمهای لاگین را در سیستم طراحی می کنیم . در مرحله دوم که سیستم کاربر را تشخیص داد ، بایستی مشخص کند که این کاربر به چه بخش هایی حق دسترسی دارد.
 
اجازه دهید تا با یک مثال ساده موضوع را بیشتر شرح دهیم ، فرض کنید شما در مرورگر اینترنتی خودتان وارد یک وبسایت شده اید و فرم ورود کاربران را باز کرده اید ، در این فرم اطلاعات کاربری خودتان را وارد نموده و دکمه ورود را کلیک می کنید ، بعد از کلیک کردن روی دکمه ورود ، سیستم وارد عملیات احراز هویت خواهد شد.
به این صورت که ابتدا اطلاعات وارد شده شما با اطلاعات موجود در دیتابیس سیستم تطبیق داده می شود تا در صورت تصدیق و تطابق اطلاعات به شما اجازه ورود به سیستم داده شود .
با فرض اینکه اطلاعات وارده با اطلاعات موجود در سیستم منطبق بود ، شما بر اساس سطح دسترسی خود  وارد بخش های مخفی نرم افزار که قبل از احراز هویت قادر به مشاهده آنها نبودید خواهید شد.
 
حال که با کلیات این فرایند آشنا شدیم بیایید کمی هم وارد جزئیات و روش های فنی پیاده سازی شویم . تا اینجای کار ما صرفا بصورت اجمالی به شرح عملیات احراز هویت پرداختیم ولی نگفتیم که سیستم برای انجام این فرایند چطور عمل می کند.
برای اینکه توضیحات برای شما ملموس تر واقع شود ، ما فرض را همان وبسایت در نظر میگیریم که یک نرم افزار تحت وب محسوب می شود و به لحاظ تعدد کاربران ، احراز هویت یکی از مهم ترین بخش های این نوع نرم افزارها بشمار میرورد . 
 
برای پیاده سازی فرایند احراز هویت در نرم افزارهای تحت وب ، از مرحله تشخیص تا صدور مجوز دسترسی برای کاربر ، سناریوها و روش های مختلفی وجود دارد که بخش تشخیص (Authentication   ) در اکثر سیستم ها مشابه بوده و معمولا بوسیله طراحی یک فرم لاگین و عمل مقایسه اطلاعات ورودی کاربر با دیتابیس ، این فرایند پیاده سازی می شود  ولی مجوز دسترسی  (Authorization  ) بطور کلی به چند روش مختلف قابل انجام است که دو مورد از مهم ترین آنها به شرح زیر میباشد :
1 – روش مبتنی بر سشن ها – کوکی ها             2 – روش مبتنی بر توکن
روش مبتنی بر سشن ها و کوکی ها رایج ترین روش تا به امروز بوده است و هم اکنون نیز توسط بسیاری از اپلیکیشن های تحت وب استفاده می شود ولی با توسعه زیرساخت های نرم افزاری ، بدلیل یکسری ضعف ها بتدریج جای خود را به روش های دیگر می دهد . 
قبل از اینکه به مکانیزم عمل این روش بپردازیم بهتر است کمی درباره سشن ها بدانیم . سشن ها متغییرهایی هستند که بر روی حافظه رم کامپیوتر سرور ایجاد می شوند و می توان اطلاعات مورد نظر خود را درون آنها نگهداری کرد . ویژگی جالب این نوع متغییرها در آن است که وقتی در یکی از صفحات وبسایت متغییری از نوع سشن ایجاد و مقدار دهی می شود ، می توان در تمامی صفحات دیگر وبسایت نیز به آن دسترسی داشت. 
وقتی کاربری وبسایت فرضی شما را از طریق مرورگر اینترنتی خود درخواست می کند ، سرور برای تشخیص کاربر و تمییز ایشان با سایر کاربران ، یک سشن برای این کاربر بر روی کامپیوتر سرور ایجاد میکند و یک شناسه منحصر بفرد هم به آن اختصاص می دهد و این شناسه را برای مرورگر هم ارسال میکند تا در درخواست های ثانویه مرورگر ، بتواند تشخیص دهد که درخواست کننده با این شناسه همان شخص قبلی بوده است .
" دقت کنید که به محض ورود یک کاربر به وبسایت شما ، سرور بطور خودکار و بدون نیاز به برنامه نویسی یک فایل متنی بنام سشن برای نشست آن کاربر ایجاد میکند که این فایل یک شناسه دارد و فعلا خالی از اطلاعات میباشد و برنامه نویس می تواند با تعریف متغییرهایی از نوع سشن درون این فایل اطلاعات مورد نظر خود را بنویسد لذا نباید به اشتباه تصور شود که وقتی هیچ متغییری از نوع سشن توسط برنامه نویس ایجاد نشده پس چطور سشن برای اون کاربر در سیستم وجود دارد ، همانطور که عرض کردم فایل سشن را خود سرور ایجاد میکند و شناسه آن را نیز خودش بصورت یونیک تولید می کند ولی برنامه نویس ، صرفا متغییرهای سشن را تعریف میکند و این معنایش این هست که حتی اگر برنامه نویس سایت ، هیچ متغییر سشنی هم تعریف نکرده بود ، سرور خودش یک سشن با یک شناسه منحصر بفرد در زمان ورود کاربر به سایت ایجاد می کند و این سشن یک متغییر نیست بلکه فایلی هست که متغییرهای سشن را در بر دارد . "
 
لذا در روش مبتنی بر سشن ، پس از انجام عملیات لاگین توسط کاربر و پروسه احراز هویت توسط سرور ، مجوز دسترسی و سطوح دسترسی کاربر ، صادر شده و در درون متغیری از جنس سشن در فایل سشن مربوط به آن کاربر  بر روی کامپیوتر سرور نوشته میشود .
توجه کنید که شناسه این سشن ( SSID ) در زمان ورود کاربر به اولین صفحه از وبسایت توسط سرور تولید شده بود و از طریق هدرها به مرورگر اینترنتی کاربر نیز ارسال شده است و هم اکنون این شناسه در درون متغییری بنام کوکی در داخل مرورگر نیز ، تا پایان نشست نگهداری خواهد شد . توجه کنید که در درون مرورگر صرفا یک شناسه بنام شناسه سشن ذخیره می شود که مشخص کننده یک سشن خاص بر روی سرور میباشد . پس وقتی یک کاربر با یک شناسه سشن خاص در  سیستم لاگین کرده بود ، سرور با شناسه نشست کاربر ، درخواست های بعدی این کاربر را به همان نشست نسبت می دهد و به این شکل تشخیص می دهد که این کاربر با این شناسه سشن لاگین کرده و مجوز دسترسی ایشان هم درون فایل سشنی با همان شناسه بر روی سرور موجود میباشد .
از آن پس سیستم برای تشخیص اینکه کاربر ، احراز هویت شده یا خیر به محتوای سشن مربوط به اون کاربر مراجعه کرده و در صورت وجود متغیر سشنی مبنی بر لاگین موفقیت آمیز کاربر در درون فایل سشن متعلق به آن کاربر ، اجازه دسترسی به بخش های مخفی نرم افزار را با توجه به سطح دسترسی نوشته شده در متغییرهای سشن به ایشان می دهد و در غیر اینصورت کاربر را به صفحه لاگین هدایت می کند .
در این روش برنامه نویسان از امکان کوکی ها برای تسهیل عملیات احراز هویت در دفعات بعدی مراجعات کاربر به سیستم نیز استفاده میکنند به این صورت که وقتی کاربر ، وبسایت را با بستن مرورگر خود ترک نمود اطلاعات لاگین کابر در درون متغییری از نوع کوکی ، بر روی مرورگر کاربر ذخیره می شود و در صورت مراجعه مجدد کاربر به وبسایت ، سیستم ابتدا وجود کوکی های مرتبط با لاگین را بررسی کرده و در صورت وجود کوکی مرتبط در مرورگر ، بلافاصله بطور خودکار وارد عملیات احراز هویت شده و در صورت تصدیق اطلاعات کوکی با اطلاعات موجود در دیتابیس ، مجددا یک سشن برای کاربر در سمت سرور ایجاد می کند و کاربر قادر به مشاهده بخش های مخفی نرم افزار خواهد بود ، به عبارتی از امکان کوکی علاوه بر ذخیره شناسه سشن برای تشخیص درخواست های بعدی کاربر ، در کاربردهای دیگر مثل حفظ لاگین در مراجعات بعدی نیز  می توان استفاده نمود .
هدف از ذکر این کاربرد از کوکی ها صرفا برای بیان روش های تسهیل عملیات لاگین در مراجعات بعدی کاربر به سایت بود تا کاربر در دفعات بعدی مراجعات خود نیازی به وارد کردن اطلاعات هویتی خود نداشته باشد ، چون سشن ها با بستن مرورگر حذف می شوند و سرور در مورد احراز هویت مبتنی بر سشن ها ، صرفا از کوکی ها جهت نگهداری شناسه نشست (SSID) استفاده می کند و ذکر کاربردهای دیگر کوکی ها در اینجا برای آگاهی بیشتر شما در خصوص تکنیک های مرتبط میباشد .
 به عنوان مثال وقتی شما وارد حساب کاربری ایمیل خود در یاهو می شوید ، این وبسایت اطلاعات لاگین شما را درون حافظه کوکی مرورگر  شما ذخیره می کند تا اگر مثلا فردای آنروز هم شما قصد مشاهده ایمیل های خود داشتید نیازی به عملیات لاگین نباشد و مرورگر بطور خودکار اطلاعات لاگین را  بجای شما برای سایت یاهو ارسال کند و سایت یاهو با این اطلاعات عملیات تشخیص و صدور مجوز دسترسی را انجام داده و در صورت درست بودن ، مجددا یک سشن برای شما ایجاد کند .
نکته ای که در خصوص استفاده از کوکی ها برای تسهیل روند احراز هویت باید از منظر یک برنامه نویس به آن توجه کنیم این است که در صورتیکه اگر کاربر از طریق یک سیستم عمومی مثل کامپیوتر کافی نت وارد حساب کاربری خود شد  سپس مرورگر را بسته و سیستم را ترک نماید ،  به خاطر اینکه کوکی ها هنوز روی مرورگر آن سیستم وجود دارد ، حساب ایشان می تواند در معرض سو استفاده دیگر کاربران قرار بگیرد طوریکه اگر کاربر دیگری با همان سیستم ، آن وبسایت را باز نمود  ، بدون عملیات لاگین و بطور خودکار توسط اطلاعات کوکی مرورگر بجای شخص اول وارد حساب کاربری ایشان خواهد شد که لازم است برای مقابله با این نوع تهدیدات امنیتی یک دکمه خروج در برنامه تعبیه شود و در رویداد کلیک این دکمه کلیه سشن ها و کوکی ها پاکسازی شود و حتما کاربر را از  وجود کوکی بر روی مرورگر مطلع نمائیم تا در صورتی که از یک سیستم عمومی برای ورود به حساب شخصی خود استفاده نمود بعد از اتمام کار حتما دکمه خروج از سیستم را فشار دهد و بدون این کار مرورگر را نبندد.
 
پس تا اینجای کار ما یاد گرفتیم که یکی از روش های صدور مجوز دسترسی (Authorization  ) در ساختارهای احراز هویت ، استفاده از روش مبتنی بر سشن ها میباشد که در این روش کاربر یکبار وارد سیستم می شود و اطلاعات اینکه این کاربر وارد سیستم شده یا خیر درون یک سشن  تا پایان نشست کاربر نگهداری می شود و سرور برای تشخیص کاربر در درخواست های ثانویه پس از لاگین ، شناسه سشن را درون کوکی مرورگر تا پایان نشست ، حفظ میکند و در هر درخواست بین مرورگر و سرور این شناسه از طریق هدر برای سرور توسط مرورگر ارسال می شود و سرور با این مکانیزم  ، مرورگر و در اصل کاربر رو تشخیص میدهد.
 
تا اینجای کار همه چیز خوب پیش رفت و ما توانستیم بدون هیچ مشکلی یک سیستم احراز هویت مبتنی بر سشن ها و کوکی ها پیاده سازی کنیم ولی تصور کنید که برنامه کلاینتی که قرار است به وبسایت شما دسترسی داشته باشد یک مرورگر اینترنتی نیست ، بنظر شما آیا باز هم می توان از این ساختار برای احراز هویت استفاده کرد . لطفا کمی در موردش فکر کنید . 
خوب من پاسخ را خدمت تان عرض می کنم ، اگر کاربران از طریق یک برنامه دیگری مثل یک اپلیکیشن بخواهند به برنامه شما دسترسی داشته باشند اگر آن برنامه از کوکی ها پشتیبانی نکند این روش احراز هویت جوابگو نخواهد بود . 
همانطور که در توضیحات روش مبتنی بر سشن – کوکی عرض کردیم ، درسته که سشن در سمت سرور ایجاد می شود و هیچ وابستگی به نوع برنامه کلاینت ندارد ولی این را هم گفتیم که شناسه اون سشن هم باید در درون کوکی برنامه کلاینت ذخیره شود تا در درخواست های ثانویه ، سرور بدنبال فایل سشن با شناسه ای که مرورگر ارسال می کند برود و از اطلاعات داخل این سشن برای احراز هویت ثانویه کاربر استفاده کند ولی اگر برنامه کلاینت ، یک مرورگر اینترنتی نباشد اصلا کوکی در کار نیست که این شناسه سشن درون آن ذخیره شود و به همراه درخواست ها برای سرور ارسال گردد ، مگر اینکه در برنامه کلاینت ساختار کوکی همانند مرورگر بصورت مجزا پیاده سازی شود .
پس اگر فرض کنیم که برنامه ما یک وبسرویس تحت وب میباشد که قرار است کلاینت های مختلفی از جمله اپلیکیشن های موبایل و غیره بهش وصل شوند و درخواست عملیات لاگین ارسال کنند ، در صورتیکه برنامه ارسال کننده درخواست یک مرورگر نباشد ، حتی بعد از لاگین ، برای اجرای درخواست بعدی اش بایستی مجددا لاگین کند چون سیستم نمی داند که این کاربر چند لحظه پیش لاگین کرده است که به اصطلاح این ضعف Stateless بودن پروتکل HTTP را به کمک کوکی  و سشن ها برطرف میکردیم که چون این کلاینت ها فاقد کوکی هستند لذا سرور هیچ سرنخی برای تشخیص رد پای سابقه قبلی کاربران نخواهد داشت ، در این نوع کلاینت ها در زمان ارسال درخواست برای سرور هیچ شناسه سشنی از طریق هدر به سرور ارسال نمی شود و سرور متوجه نخواهد شد که این شخص درخواست کننده همان شخصی هست که با فلان شماره سشن چند لحظه پیش لاگین کرد .
 اگر خاطرتون باشه مبنای تشخیص کاربران در روش مبتنی بر سشن ها و کوکی ها همین شناسه سشن بود و وقتی برنامه کلاینت اصلا کوکی نداشته باشد پس چنین شناسه ای اصلا قابلیت ذخیره در محل کوکی برنامه کلاینت رو هم نخواهد داشت بنابراین در هیچ از یک از درخواست ها ، شناسه سشنی برای سرور ارسال نخواهد شد  و سرور قادر به تشخیص کاربر نخواهد بود تا عملیات لاگین قبلی ایشان را به خاطر بیاورد  و در هر بار ارسال درخواست ، سرور کاربر را به عنوان یک کاربر جدید تصور خواهد کرد.
احراز هویت مبتنی بر توکن
 

بنابر آنچه گفته شد ما برای اینکه در برنامه های کلاینت فاقد کوکی ، شناسایی کاربر را برای سرور مهیا کنیم بایستی مکانیزمی در سمت سرور و برنامه کلاینت آماده کنیم تا در اولین ورود کاربر به سیستم یک شناسه برای ایشان تولید شده و در اختیار برنامه کلاینت قرار داده شود که این شناسه در برنامه کلاینت درون حافظه محلی برنامه ذخیره شده و در درخواست های بعدی برای کمک به سرور جهت تشخیص اینکه ارسال کننده چه کسی هست استفاده شود.
به عبارتی دیگر ما بایستی خودمان بصورت دستی یک زیرساخت برای تولید شناسه منحصر بفرد کاربران در سرور ایجاد کنیم و این شناسه را بعد از لاگین کاربر در اختیار برنامه کلاینت قرار بدیم تا اون برنامه در درخواست های بعدی ، این شناسه را هم به همراه درخواست برای سرور ارسال کند تا به سرور بگوید که من همانی هستم که قبلا لاگین کردم و تو این شناسه را در اختیار من قرار دادی و این کار را بایستی  بدون نیاز به کوکی انجام دهیم ، این شناسه همان توکن میباشد.
اگر بخواهید روش مبتنی بر توکن را به همین سادگی که من گفتم پیاده سازی کنید که می توانید این محدودیت را دور بزنید و بتوانید سیستم احراز هویت را در برنامه های کلاینت فاقد امکان کوکی پیاده سازی کنید که خیلی ساده بعد از لاگین یک شناسه به عنوان رمز ورود از سرور بگیرید و در درخواست های بعدی برای سرور ارسال کنید ولی در این حالت شما بایستی توکن تولید شده را در دیتابیس سرور نیز ذخیره نمائید و یک فیلد مجزایی هم در دیتابیس برای زمان انقضای توکن اضافه کنید و در هر درخواتسی هم عمل تطبیق با دیتابیس بایستی انجام شود که این کار بار اضافی روی سرور ایجاد میکند و یکسری نقص امنیتی هم خواهد داشت ولی اگر امنیت در سیستم شما چندان مهم نیست و تعداد کاربران شما هم خیلی زیاد نیستند این نقص ها قابل چشم پوشی میباشند ولی اگر همه این موارد برایتان حیاتی و جدی هستند توصیه می شود از ساختار های رمز کننده بدون وابسته به دیتابیس استفاده کنید که معروفترین ساختار مبتنی بر توکن روش JWT میباشد که می توانید در این روش کل اطلاعاتی که قبلا بعد از لاگین کاربر در سشن کاربر نگهداری می کردید ، با یک کلید خصوصی بصورت رشته ای رمز شده در بیاورید و این اطلاعات رمز شده همان توکن شما باشد که بعد از لاگین کاربر در اختیار برنامه کلاینت قرار داده خواهد شد .
در این حالت توکن دارای کلیه اطلاعات مورد نظر شما از کاربر میباشد و حتی اگر در اختیار دیگران هم قرار داده شود قادر به تجزیه اطلاعات کاربر بدون کلید خصوصی نخواهند بود و برای احراز هویت در دفعات بعدی نیز سرور نیازی به ارتباط با دیتابیس نخواهد داشت ، چون همه اطلاعات مورد نظر در درون خود توکن رمز شده و سرور برای دادن دسترسی به کاربر فقط کافیست این توکن را با  همان کلید خصوصی که در زمان Encode کردن رمز کرده بود Decode کند و اگر دیکد شد یعنی توکن معتر هست و اگر نشد یعنی توکن دریافتی از کلاینت نامعتبر میباشد .
حتی می توان اطلاعات اضافی مثل زمان انقضا و سطوح دسترسی را درون توکن   JWT نگهداری کرد تا در زمان دیکد کردن به این اطلاعات دسترسی داشت و عملیات مورد نظر را انجام داد.
اجازه بدید توضیح بیشتری در مورد JWT خدمتتون عرض کنم ، 
در این الگو، یک توکن ایجاد میشود که از سه بخش تشکیل شده است و این سه قسمت با . (Dot) از هم جدا می شوند . کدام از این بخش ها جداگانه با Base64 انکود میشن
Header: در بخش هدر اطلاعاتی مانند نوع توکن و الگوریتم کدگذاری نوشته می شود.
Payload: اطلاعاتی که قرار است بین سرور و کلاینت رد و بدل شود در این بخش نوشته می شود ، مانند: کد کاربر یا تاریخ انقضا توکن یا هر چیز دیگری
Signature: بخش سوم هم امضا هست. برای تولید امضا Header و Payload (که Base64 Encoded هستن) با . به هم وصل می شوند  و رشته ی نهایی با Secret Key که داریم و الگوریتمی که در هدر مشخص شده امضا میشه. این امضا برای این هست که در سرور مقایسه صورت بگیرد و اصالت توکن بررسی شود .
همانطور که مشخص هست، Header وPayload به راحتی قابل خوانده شدن هستند و کافیه فقط Base64 Decode بشوند
با این تفاسیر، سرور اصلاً توکن های تولید شده را در جایی ذخیره نمی کند ، و فلسفه تولید این نوع از توکن ها نیز این هست که این مرحله حذف شود  و توکن هایی تولید شوند که بدون نیاز به چک کردن با دیتابیس، اصالتشان تایید گردد .
زمانیکه سرور توکن رو دریافت می کند ، یکبار دیگر اطلاعات را Sign کرده و Signature تولید شده رو با Signature موجود در Token مقایسه می کند ، اگر اینها یکی بودن یعنی توکن معتبر هست. چون در این روش از کلید خصوصی برای Sign/Verify استفاده میشود ، مهم است که این کلید ترکیب رندومی از کاراکترها باشد و از آن حفاظت شود .

در سمت کلاینت توکن باید ذخیره گردد ،  مشخص هست که هر توکن خاص معرف یک کاربر خاص هست و اگر توکن ارسال شود ، سرور تشخیص میدهد که این درخواست از سمت آن کاربر خاص آمده است ، حالا اگر شخصی آن توکن رو از شما سرقت کند ، و آنرا به سرور ارسال کند ، میتواند وارد اکانت شما شود . اما موضوع این هست که اگر شخصی این دسترسی رو داشته باشد ، سرقت یوزرنیم و پسورد شما هم میتواند به همان راحتی باشد .
اگر نیاز دارید میتوانید در Payload اطلاعات بیشتری مثل IP یا هر مشخصه ی دیگر را هم بفرستید (که بعداً در سرور این را  با IP درخواست دهنده مقایسه کنید)، اما بنظر بنده کمکی نمی کند ، چون تمام اطلاعاتی که از سمت کلاینت دریافت می شوند میتواند جعلی بوده و هیچوقت، نباید به اطلاعاتی که از سمت کلاینت ارسال می شود اعتماد کرد.
اینکه چه اطلاعاتی رو در Payload میفرستید دست خودتان هست، اما توجه داشته باشید که این اطلاعات به راحتی قابل خواندن هستند . در زمان استفاده از توکن ، هیچ Sessionی وجود ندارد، این توکن همان کار Session رو انجام میدهد ، فقط باید خودتان مدیریت نمائید .
برای هر درخواست بررسی صحت توکن انجام می گردد ، یعنی وقتی شما سیستم Token-Based طراحی می کنید، همیشه نوعی از بررسی را روی این توکن در هر درخواست انجام میدید. 
اصولاً باید بر اساس نیازهایی که پروژه تان دارد ، راه حل مناسب رو انتخاب کنید، هیچ روشی در دنیای برنامه نویسی وجود ندارد که برای همه ی حالت ها و کاربردها، بهترین انتخاب باشد . 
با یک مثال واقعی کاربرد این الگو مشخص تر می شود .
مسئولیت اصلی من توسعه ی APIهایی هست که اجازه ی ارتباط با سرور رو به کلاینت ها میدهد (برنامه نویسی  Backend)، ایده ی من این هست که این API هسته ای رو شکل میده که کلاینت ها باهاش ارتباط برقرار می کنن، و تفاوتی ندارد که این کلاینت یک برنامه ی اندرویدی هست یا مرورگر. یعنی با همین API باید بشود وب سایت را طراحی کرد، برنامه ی Android, iOS و... را هم طراحی کرد.
در این حالت برای احراز هویت من به سمت Token میروم .  همانطور که میدانید درخواست های Http حالت Stateless دارند ، یعنی در این پروتکل خصوصیتی وجود ندارد که درخواست اول یک کاربر را  به درخواست دوم کاربر ارتباط بدهد تا سرور متوجه شود اینها همه از طرف یک کابر واحد می آیند (بین درخواست اول و دوم میتواند از چند میلی ثانیه تا ساعتها اختلاف زمانی وجود داشته باشد ). Session برای همین منظور ایجاد شد است ، درواقع سشن واسطه ای هست تا درخواست های یک کاربر در یک بازه ی زمانی مشخص را به هم ارتباط دهد. برای اینکار هم یک ID (در واقع یک توکن) تولید می کند که وظیفه ی ارتباط درخواست ها به همدیگر را به عهده دارد و برای استفاده از این قابلیت یک استانداردی تعریف شده است که سرور و کلاینت ها با آن آشنا هستند .
اگر چنین سیستمی را طراحی کرده باشید، میدانید که دیتابیس قلب سیستم هست و بیشتر از هر بخش دیگری منابع مصرف می کند. در سرور یکی از منابع مهم و پر مصرف رم هست و CPU در خیلی از موارد بلا استفاده می ماند و مهمترین مصرف کننده ی رم هم همین دیتابیس هست. مثلاً اگر دیتابیس و اپلیکیشن همه روی یک سرور قرار داشته باشند ، در اغلب موارد تا ۸۵ درصد از رم در اختیار دیتابیس قرار داده می شود .
در این حالت ترجیح این هست که درخواست های دیتابیس رو کمتر کنیم تا این منبع مهم صرف بخش های پر اهمیت تر شود . تا جایی که امکان دارد پردازش ها را سمت اپلیکیشن انجام دهیم  و از مکانیزم های Caching استفاده کنیم تا از درخواست های دیتابیسی جلوگیری شود .
اگر یک API داشته باشیم که تعداد زیادی مصرف کننده داشته باشد ( به عنوان مثال قصد سرویسی مانند: Instagram ) و نیاز به احراز هویت داشته باشیم، ترجیح من این هست که درخواست های دیتابیسی را برای بخش های مهم تر نگه دارم  لذا JWT اینجا برای من کاربرد خوبی خواهد داشت که یک توکن بدون نیاز به ثبت در دیتابیس ایجاد میشود و می شود اصالتش رو تایید کرد و در درون همین توکن همه ی اطلاعات موردنیازمان را ذخیره کنیم.
می دانید که برای استفاده از این توکن ها، درصورتی که در دیتابیس پیاده سازی شوند ، نیاز به ذخیره ی اطلاعات دیگری کنار همین توکن دارید، مثلاً کد کاربر، دسترسی های کاربر، تاریخ اعتبار توکن و هر اطلاعات دیگری که اپلیکیشن شما نیاز دارد . ذخیره این ها در دیتابیس منابع بیشتری را هم از سیستم میگیرد ولی در JWT میشود همه این اطلاعات را در خود توکن ذخیره کرد و هیچ محدودیتی هم ندارید، برخلاف دیتابیس که به هرحال همیشه محدودیت ها و ملاحظاتی در تعداد فیلد هایش وجود دارد .

تا به اینجای کار با JWT  ما توانستیم فشار را  از دوش دیتابیس برداریم و بسمت اپلیکیشن هدایت کنیم (یعنی به ازای هر درخواست حداقل یک Database Trip کمتر داریم) که استفاده از این روش یک نوع بهینه سازی سیستم نیز محسوب میشود . 
مسلماً در حالتی که این اطلاعات در دیتابیس ذخیره نمی شوند ، ما نمی توانیم آنالیزی روی آنها نیز انجام دهیم ، پس اگر اپلیکیشن ما نیاز به این آنالیزها دارد (به عنوان مثال : هر کاربر آخرین بار چه زمانی لاگین کرده) یا باید از JWT استفغاده نکنیم و یا اینکه با بررسی سیستم ، از JWT در کنار دیتابیس بصورت ترکیبی از هر دو روش استفاده کنیم . به عنوان مثال اگر درصورتی که در روش دیتابیس تنها، به ازای هر درخواست تعداد 3 فقره Database Trip داریم  و اگر JWT را در کنارش استفاده کنیم تعداد به ۱ DB Trip تقلیل یابد باز هم استفاده ی ترکیبی بهتر بوده و موجب بهینه سازی سیتم خواهد شد .
موضوع بعدی این هست که چون توکن ها ذخیره نمیشوند ، پس در حالت عادی قابلیت Revoke رو نخواهیم داشت (مثلاً در حالتی که یک اکانت در چند مکان متفاوت مورد استفاده قرار میگیرد و به دلیل اینکه ممکنه امنیت اکانتی به خطر افتاده باشد و بخواهیم این توکن ها رو بی اعتبار کنیم تا مجبور به لاگین دوباره باشن ) ، در این حالت یا باید JWT رو کنار بگذاریم یا اینکه با استفاده ی ترکیبی از دیتابیس و Caching Layer این قابلیت رو به سیستم خود اضافه کنیم.
در مورد سطح دسترسی هم هیچ تفاوتی در این دو روش وجود ندارد ، چون به هرحال باید این مشخصه ها در جایی نگهداری شوند ، حال یا در داخل دیتابیس و یا در خود توکن .
امیدوارم این مقاله برای شما دوست عزیز مفید بوده باشد .
در صورتیکه شما هم پیشنهادی در خصوص روشهای پیاده سازی ساختارهای احراز هویت دارید خوشحال می شویم تا در اینجا برایمان بنویسید .


آرزوی موفقیت برایتان دارم
ارادتمند شما مهدی حسامی