احراز هویت به کدام روش؟

در اینجا میخوام دو استراتژی پیاده سازی authentication رو مورد بررسی قرار بدم.

زمانی که کاربری احراز هویت شد (به هر روشی) نیاز دارد توکنی را دریافت و برای خود نگه دارد و تا زمانی که این توکن منقضی نشده بتواند به منابع - بدون نیاز به احراز هویت دوباره - دسترسی داشته باشد.

در روش stateful شما وضعیت را نگه میدارید و هر زمانی که بخواهید میتوانید آنرا باطل کنید و یا از بین ببرید. و در مقابل، روش stateless اینگونه است که شما وضعیت را کنترل نمیکنید و زمانی که برای توکن مشخص کرده اید باطل کننده آن خواهد بود.

وقتی سرور وضعیت کاربر احراز هویت شده را نگه میدارد یا stateful:

در این روش توکن صادر شده را در همان backend صادر و به ازای آن اطلاعات کاربر را بر روی session ذخیره میکنید و مقدار session را به client میدهیم. حال هر بار client بخواهد به backend دسترسی پیدا کند خود backend میداند که در session کدام کاربر درخواست دهنده است. و بدین ترتیب هر بار که session ها در سمت سرور پاک یا دستکاری شوند دیگر مقداری که به client داده بودیم بی معنی خواهد شد.

در این روش شما میتوانید در هر زمانی که بخواهید مقدار session را پاک کنید و البته پیاده سازی راحتی هم دارد. اما این روش علاوه بر مصرف زیاد حافظه، برای scale کردن مناسب نیست چرا که اگر کاربر A رو روی سرور ۱ احراز هویت کنیم پس مقدار توکن را در این سرور ذخیره کرده ایم و از این به بعد تنها سرور ۱ میتواند به درخواست های کاربر A پاسخ دهد.

مشکل دیگر این است که فرض کنید سرویس شما هم بر روی هم بر روی مرورگر و هم اپلیکیشن اندروید قابل استفاده است. در این حالت اگر کاربر دستور logout بر روی اپلیکیشن اندروید را بدهد، backend مقدار session را پاک خواهد کرد و در واقع درخواست های شما از اپلیکیشن اندروید هم دیگر بی معنی است و احراز هویت باید دوباره صورت بگیرد.

وقتی سرور از وضعیت کاربر احراز هویت شده هیچ اطلاعی ندارد یا stateless:

این روش برای رفع مشکلاتی که در بالا گفتیم ارائه شده است. در این روش backend مقدار توکن را پیش خود نگه نمیدارد و آنرا پس از ذخیره در پایگاه داده، فقط یکبار به client میسپارد.

واضخ است که در این روش دیگر نگران حافظه نخواهید بود و برای scale کردن مشکلی پیش نخواهد آمد چرا که backend تنها وظیفه اعتبارسنجی مقدار توکن را دارد و بر روی سرور ذخیره ای صورت نمیگیرد. واضح است که اگر شما از روی مرورگر logout کنید حساب کاربری شما بر روی اپلیکیشن اندروید همچنان کار خواهد زیرا شما فقط مقدار توکن ذخیره شده بر روی مرورگر را پاک کرده اید و تغییر وضعیتی در backend پیش نیامده است.

البته بر اساس این روش که کمی پیچیده تر است، شما بعنوان backend باید کاملا پایبند به توکنی که صادر کرده اید باشید چرا که نمیتوانید آنرا یکطرفه باطل کنید.

کاملا مشخص است که روش دوم کارایی بیشتری دارد اما محدودیت هایی را برای توسعه ایجاد میکند که برای بهبود آنها چند توصیه زیر عملکرد را بهتر خواهد کرد:

  • برای تولید هر توکن، زمانی را بعنوان انقضا مشخص کنید و به client اجازه دهید همراه با درخواست ایجاد توکن این زمان را مشخص کند.
  • مقداری را برای از نوسازی توکن و تمدید مدت آن در نظر بگیرید. (Refresh Token)