طراحی یه سیستم کوتاه کننده لینک ساده [قسمت دوم: احراز هویت و نحوه ذخیره سازی بازدید]

سلام، توی این قسمت از طراحی سیستم کوتاه کننده لینک، قراره راجع به نحوه احراز هویت و استراتژی ذخیره سازی بازدید ها به شیوه کارآمد صحبت کنم.

توی احراز هویت گزینه های خیلی زیادی با مزایا و معایب و کاربرد های خاص خودشون جلومون قرار دارن که دسته بندی های مختلفی هم مثل Session-Based و Token-Based دارن.

انتخاب من برای احراز هویت این سیستم، JWT هست. با یه access-token و یه refresh-token اما چرا JWT؟ با ذخیره سازی اطلاعات مورد نیازمون از یوزر توی payload توکن می‌تونیم به دیتابیس کوئری نزنیم که البته این قضیه trade-off های خودش رو مثل out-date شدن اطلاعات داره که اینجا برای ما دغدغه جدی‌ای نیست چون سیاست refresh-token رو هم داریم و این باعث میشه access-token هامون توی یه بازه زمانی مشخص re-new بشن و اطلاعات هم آپدیت بشن طبیعتا.

دیاگرام احراز هویتمون به شکل بالا میشه.

فِلوی کلیمون اینطوری میشه که کاربر میاد با identifier (که در حال حاضر email کاربر هست) و رمز عبورش احراز هویت می‌کنه و access_token و refresh_token رو دریافت می‌کنه و refresh_token روی رکورد User ذخیره میشه تا در صورتی که access_token کاربر لو رفت بریم و refresh_token رو عوض کنیم تا بعد از تموم شدن expire time توکن دیگه نتونه رفرش بکنه.

زمان انقضای access_token رو من ده دقیقه مد نظرم هست و refresh_token رو هم یک هفته. (دلیل خاصی هم ندارم که چرا دقیقا این دو تا زمان رو انتخاب کردم)

پس جدول یوزرمون نیاز به یه فیلد جدید داره برای ذخیره سازی refresh_token.

دیاگرام آپدیت شده دیتابیسمون
دیاگرام آپدیت شده دیتابیسمون

توی ذخیره سازی refresh_token توجه داشته باشید که باید اون رو hash کنیم و ذخیره بکنیم، اما چرا؟ بیاید حالتی رو بررسی کنیم که بدون هش ذخیره سازی کردیم، اگه به هر دلیلی یه مشکل امنیتی پیش بیاد و بشه رکورد های جدول User رو بیرون کشید، رفرش توکن همه یوزرهامون لو میره پس هکر می‌تونه حساب بخش زیادی از کاربرامون رو استفاده بکنه. (دلیل اینکه تمام حساب ها رو نمی‌تونه استفاده بکنه اینه که ممکنه یه سری از رفرش توکن هامون منقضی شده باشن و کاربر هم اخیرا لاگین نکرده باشه در نتیجه غیر قابل استفاده باشه)

الگوریتمی که برای هش password و refresh_token توی دیتابیس استفاده می‌کنیم bcrypt هست تا امکان استفاده از rainbow table برای رسیدن به مقدار اصلی وجود نداشته باشه.


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

زمانی که من به عنوان یه کاربر آدرس xxxx.ir/gxqw1 رو توی مرورگر باز می‌کنم نیازم اینه که سریع به آدرس مقصد redirect بشم و اینکه ما می‌خوایم بازدید رو ذخیره کنیم نباید باعث بشه کاربر کندی رو حس بکنه و insert کردن توی جدول با دیتای بالا مخصوصا زمانی که index وجود داره روی فیلد هاش یه میزان زمانی رو می‌طلبه. اینجاست که Job Queue رو نیاز داریم استفاده بکنیم تا صرفا یه کار (ذخیره اطلاعات بازدید) رو تعریف بکنیم که نیازه انجام بشه ولی اینکه دقیقا کی انجام میشه برامون مهم نیست.

درسته که اینجا برای اضافه کردن Job مد نظرمون به Job Queue هم زمان نیازه ولی نسبتش وابسته به مکانی که برای ذخیره سازی Job ها در نظر می‌گیریم می‌تونه خیلی کمتر باشه.

اینطوری باعث میشیم مدت زمانی که لازمه برای ذخیره سازی بازدید به response time کاربر اضافه نشه.


لطفا به کامنت های این پست اهمیت بدید چون ممکنه دوستان اشتباهات من رو اصلاح کرده باشن و نظرات متفاوتی رو ببینیم.
محمد محمدعلیان | 29 فروردین 1401
کانال تلگرامم | لینکدینم