احراز هویت در وب: کوکی‌ها در مقابل توکن‌ها

آفلاین
user-avatar
عرفان حشمتی
18 مهر 1400, خواندن در 11 دقیقه

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

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

احراز هویت مبتنی بر کوکی

احراز هویت فرایند اعتبارسنجی اطلاعات کاربر برای یک هویت منحصر به فرد است.

در احراز هویت مبتنی بر کوکی، یک شناسه (کوکی) منحصر به فرد در سمت سرور ایجاد شده و به مرورگر ارسال می‌شود.

هنگام ورود به یک برنامه وب، مرورگر شما یک کوکی از سرور برنامه دریافت کرده و آن را ذخیره می‌کند، سپس با هر درخواست بعدی آن کوکی را ارسال می‌نماید تا تأیید کند که درخواست‌ها از یک کاربر آمده است.

برای درک بهتر نحوه عملکرد کوکی‌ها، بیایید این فرآیند را به 5 دسته تقسیم کنیم.

1. ورود (لاگین) کاربر به برنامه از طریق اعتبارسنجی.

2. سرور اطلاعات را تأیید کرده و یک سشن در پایگاه داده ایجاد می‌کند.

توجه: اگرچه امکان ایجاد سشن در حافظه هم وجود دارد، اما مقیاس پذیر نیست.

3. سرور با قرار دادن کوکی در مرورگر که حاوی هدر Set-Cookie است، پاسخ را برمی‌گرداند.

این کوکی به عنوان یک جفت name و value ارسال می‌شود و حاوی یک شناسه منحصر به فرد برای شناسایی کاربر است.

علاوه بر این، کوکی می‌تواند حاوی جزئیاتی مانند تاریخ انقضا، دامنه و موارد دیگر باشد. نمونه پاسخ به همراه چند هدر Set-Cookie به شکل زیر است:

HTTP/2.0 200 OK
Content-Type: text/html
Set-Cookie: <cookie-name>=<cookie-value>
Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<number>
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain>
Set-Cookie: <cookie-name>=<cookie-value>; Path=<path>
Set-Cookie: <cookie-name>=<cookie-value>; Secure
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly

[page content]

توجه: همچنین می‌توانید از یک هدر Set-Cookie برای تنظیم چند خصوصیت استفاده کنید:

(Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain>; Secure; HttpOnly).

4. مرورگر کوکی را در حافظه ذخیره کرده و با درخواست‌های بعدی ارسال می‌کند.

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

می‌توانید همه کوکی‌های ذخیره شده در مرورگر خود را در محل ذخیره سازی کوکی‌ها با استفاده از ابزار dev پیدا کنید.

5. هنگامی که کاربر از سیستم خارج می‌شود (به اصطلاح Logout می‌کند)، سرور سشن را از پایگاه داده حذف می‌کند.

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

از آنجا که اکنون نحوه عملکرد احراز هویت مبتنی بر کوکی را درک کرده‌اید، بیایید ویژگی‌ها، مزایا و معایب آن را بررسی کنیم.

  • فرایندی کاملا خودکار

اگر از کوکی‌ها برای احراز هویت استفاده می‌کنید، نیاز به توسعه چیزی برای افزودن کوکی‌ها به درخواست‌ها ندارید.

به علاوه مرورگر از نحوه مدیریت کوکی‌ها مراقبت کرده و به طور خودکار کوکی را برای همه درخواست‌ها اضافه می‌کند.

اگرچه این فرآیند خودکار باعث می‌شود توسعه‌دهندگان به راحتی کار کنند، اما معایبی هم دارد. به عنوان مثال برخی از درخواست‌ها نیازی به احراز هویت ندارند. اما با این رویکرد، کوکی در هر درخواست ارسال می‌شود.

همچنین مهاجمان CSRF می‌توانند با استفاده از این مکانیزم مرورگر را فریب دهند و درخواست‌هایی جعلی به وب سایت ارسال کند.

  • معیارهای امنیتی

به طور پیش فرض، احراز هویت مبتنی بر کوکی از حفاظت بالایی در برابر حملات برخوردار نیست و عمدتا در برابر XSS و CSRF آسیب پذیر است.

اما می‌توانیم هدرهای کوکی را طوری تغییر دهیم تا در برابر چنین حملاتی محافظت شوند.

به عنوان مثال، کوکی‌ها را می‌توان با استفاده از ویژگی HttpOnly هنگام تنظیم هدرهای کوکی به راحتی در برابر حملات XSS محافظت کرد.

Set-Cookie: <cookie-name>=<cookie-value>; Secure
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly

همچنین می‌توانیم از ویژگی SameSite در هدر کوکی برای جلوگیری موثر از حملات CSRF استفاده کنیم.

Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Lax

سه مقدار وجود دارد که می‌توان برای ویژگی SameSite استفاده کرد:

  • SameSite=Lex مطمئن می‌شود که مرورگر در درخواست‌های cross-site کوکی ارسال نمی‌کند (اگر هم ویژگی SameSite را تعریف نکنید، به صورت پیش فرض در کوکی‌ها اعمال می‌شود).
  • SameSite=Strict مطمئن می‌شود که مرورگر کوکی را فقط برای درخواست‌های same-site ارسال می‌کند.
  • SameSite=None به شما امکان می‌دهد کوکی‌ها را هم با درخواست‌های cross-site و هم same-site ارسال کنید.

 

  • معمولا روی یک دامنه کار می‌کند

کوکی‌ها فقط در یک دامنه واحد کار می‌کنند، مگر اینکه آن را به طور خاص پیکربندی کرده باشید.

اگرچه از بیرون یک محدودیت به نظر می‌رسد، اما به طور پیش فرض یکی از قوی‌ترین ویژگی‌ها برای تقویت single-origin است.

با این حال اگر فرانت-اند و بک-اند شما در دامنه‌ها یا زیردامنه‌های مختلف قرار داشته باشد، باید صراحتا آن را در کوکی تعریف کنید. در غیر این صورت، مرورگر کوکی را به همراه درخواست ارسال نمی‌کند.

  • برای APIها مناسب نیست

اگر در حال ساختن یک API برای ارائه خدمات خود به مشتریان هستید، کوکی‌ها راه حل مناسبی نیستند. مگر اینکه خود کلاینت یک مرورگر باشد، در این صورت همه چیز برای کلاینت پیچیده می‌شود.

به عنوان مثال اگر می‌خواهید اپلیکیشن تلفن همراه ایجاد کنید، داشتن کوکی در مقایسه با توکن، مدیریت آن را برای برنامه مورد نظر دشوار می‌کند.

  • وجود مشکلات مقیاس پذیری

همانطور که قبلا ذکر شد، سرور مسئول پیکربندی کوکی است و ما باید سشن‌ها را در پایگاه داده برای هر کاربر ذخیره کنیم.

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

اما با افزایش تعداد کاربران، مقیاس بندی و مدیریت سشن‌ها ممکن است با مشکلاتی همراه باشد.

  • مناسب برای ذخیره اطلاعات اضافی

از آنجا که این روش سشن‌های جداگانه‌ای را برای هر کاربر در نظر می‌گیرد، بنابراین می‌توانیم داده‌های متصل به سشن را ذخیره کنیم.

با بهره گیری از کوکی‌ها و سشن‌ها می‌توانیم داده‌های خاصی مانند شخصی سازی کاربر و کنترل دسترسی را ذخیره کنیم. سپس به ما اجازه می‌دهد تا از آن برای درخواست‌های بعدی استفاده نماییم.

هرچند انجام این کار با توکن‌ها نیز امکان پذیر است. به عنوان مثال از طریق توکن‌های JWT می‌توانیم داده‌های Claims را ذخیره کنیم. اما از آنجا که سایز توکن را افزایش می‌دهد، نگهداری بیشتر آن بر کارکرد شبکه تأثیر می‌گذارد (البته اگر تنها یک درخواست را در نظر بگیریم، ممکن است احساس نشود، اما زمانی که همه اطلاعات جمع آوری و مقیاس بندی شود، مشکلات سربار قابل مشاهده می‌گردد).

  • می‌تواند دسترسی به کوکی را در مرورگر محدود کند

از آنجا که کوکی ویژگی HTTP-Only را ارائه می‌دهد، می‌توانیم دسترسی جاوااسکریپت را برای آن محدود کنیم. علاوه بر این از هرگونه دسترسی به کوکی با حملات Cross-Site جلوگیری می‌کند.

احراز هویت مبتنی بر توکن

احراز هویت مبتنی بر توکن برای رفع چندین مشکل در روش قبل معرفی شد.

برخلاف کوکی‌ها، رویکرد مبتنی بر توکن نیاز به پیاده سازی دستی دارد و در سمت کلاینت ذخیره می‌شود.

هنگام ورود (لاگین) به یک برنامه وب، سرور اعتبار کاربر را تأیید کرده و یک توکن رمزگذاری شده به مرورگر ارسال می‌کند. سپس مرورگر این توکن را ذخیره می‌کند و می‌تواند به عنوان مجوز درخواست‌های بعدی اضافه شود.

با این حال پیاده سازی استاندارد رویکرد مبتنی بر توکن پیچیده‌تر از جریان توصیف شده در بالا است. به عنوان مثال OpenID Connect جریانهای متععد احراز هویت را معرفی می‌کند تا به انواع مختلف موارد مورد استفاده بپردازد.

برای درک بهتر نحوه عملکرد توکن‌ها، بیایید این فرآیند را به 4 دسته تقسیم کنیم و از JWT (پرکاربردترین استاندارد توکن) به عنوان نمونه استفاده نماییم.

JSON Web Token (JWT) پرکاربردترین استاندارد در احراز هویت مبتنی بر توکن است.

برای کسب اطلاعات بیشتر مقاله مقایسه JWT و Session را در وب سایت راکت مطالعه کنید.

1. ورود کاربر به برنامه از طریق اعتبارسنجی.

2. سرور پس از تأیید اطلاعات، یک توکن تولید کرده و آن را با یک کلید مخفی امضا می‌کند و به مرورگر برمی‌گرداند.

توجه: برای ایمن سازی کانال باید از رمزگذاری SSL استفاده کنید.

در سمت سرور هم می‌توانید از یک کتابخانه NPM مانند jsonwebtoken برای تولید این توکن‌ها بهره بگیرید.

// Install
npm install jsonwebtoken// Usage
var jwt = require('jsonwebtoken');
var token = jwt.sign(
              { data: user},
              privateKey,
              { algorithm: 'RS256'},
              exp: Math.floor(Date.now() / 1000) + (60 * 60),            );

توکن تولید شده از کتابخانه jsonwebtoken به شکل زیر است:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

این توکن از 3 قسمت header، payload و signature (header.payload.signature) تشکیل شده که توسط . از هم جدا می‌شوند، همچنین می‌توانید از وب سایت jwt.io برای تجزیه و تحلیل اطلاعات توکن استفاده کنید.

3. توکن در مرورگر ذخیره شده و با استفاده از جاوااسکریپت به درخواست‌های بعدی اضافه می‌گردد.

مرورگر می‌تواند این توکن را در Local Storage ، Session Storage یا Cookie Storage ذخیره کند. سپس این توکن به هدر درخواست‌های لازم اضافه می‌شود و برای اعتبارسنجی درخواست به سمت سرور ارسال می‌گردد. بنابراین افزودن یک توکن به هدر باید با استفاده از جاوااسکریپت پیاده سازی شود.

Authorization: Bearer <token>

همچنین می‌توانید از تابع ()jwt.decode در کتابخانه jsonwebtoken برای رمزگشایی توکن و استفاده از داده‌های payload در برنامه استفاده کنید.

5. هنگام خروج (Logout) کاربر از سیستم، باید توکن را به صورت دستی از فضای ذخیره سازی آن حذف کنید.

زمانی که کاربر از سیستم خارج می‌شود، باید به صورت دستی توکن ذخیره شده در فضای ذخیره سازی را پاک کرده و آن را برای درخواست‌های دیگر در دسترس قرار ندهید.

از آنجا که اکنون می‌دانید چگونه احراز هویت مبتنی بر توکن کار می‌کند، بیایید ویژگی‌ها، مزایا و معایب آن را ببینیم.

  • یک مکانیزم stateless است

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

سرور فقط مسئول ایجاد و اعتبارسنجی توکن‌ها است که به شما امکان می‌دهد راه حل‌های مقیاس پذیر بیشتری نسبت به روش مبتنی بر کوکی ایجاد کنید.

  • مسائل امنیتی

اگرچه توکن‌ها سعی می‌کنند مسائل امنیتی کوکی‌ها را برطرف کنند، اما آنقدر هم امن نیستند.

اگر برنامه شما اجازه دهد اسکریپت‌های خارجی در آن قرار گیرند، در نتیجه توکن‌های ذخیره شده در مرورگر می‌توانند در برابر حملات XSS آسیب پذیر باشند.

علاوه بر این از آنجا که توکن stateless است، اگر از بیرون قابل دسترسی باشد، هیچ راهی برای لغو آن تا زمان انقضایش وجود ندارد. بنابراین بسیار مهم است که توکن را تا حد ممکن حفاظت کنیم. من بسیاری از سرویس‌های احراز هویت را دیده‌ام که از 5 دقیقه به عنوان زمان پیش فرض توکن‌های JWT استفاده می‌کنند.

جمع‌بندی

رویکردهای مبتنی بر توکن و کوکی دو مکانیزم پرکاربرد احراز هویت برای برنامه‌های وب به حساب می‌آیند. در این مقاله نحوه کار آنها، ویژگی‌ها، مزایا و معایب هر کدام را مورد بحث قرار دادیم.

همانطور که دیدید، هیچ یک از این روش‌ها 100 درصد کامل نیستند و هر کدام چندین اشکال جزیی دارد.

بنابراین هنگام انتخاب روش احراز هویت، به شما توصیه می‌کنم یکی را بر اساس الزامات پروژه خود انتخاب کنید و به دنبال راه حل کامل نباشید.

منبع

چه امتیازی به این مقاله می دید؟
خیلی بد
بد
متوسط
خوب
عالی

دیدگاه‌ها و پرسش‌ها

برای ارسال دیدگاه لازم است، ابتدا وارد سایت شوید.

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

آفلاین
user-avatar
عرفان حشمتی @heshmati74
مهندس معماری سیستم های کامپیوتری، طراح و توسعه دهنده وب سایت
دنبال کردن

گفتگو‌ برنامه نویسان

بخشی برای حل مشکلات برنامه‌نویسی و مباحث پیرامون آن وارد شو