مقدمه
در توسعهی اپلیکیشنهای مدرن، امنیت یکی از ستونهای اصلی پروژه به حساب میآید. یکی از مهمترین چالشها این است که چطور توکنهای احراز هویت (مثل JWT یا Access Token) را به صورت امن ذخیره و در درخواستها ارسال کنیم.
دو روش رایج برای مدیریت توکن وجود دارد:
- ذخیره توکن داخل کوکی (معمولاً HttpOnly Cookie)
- ذخیره توکن در کلاینت (مثلاً localStorage) و ارسال آن در Authorization Header
هر کدام از این روشها مزایا، معایب و تهدیدهای امنیتی مخصوص خودشان را دارند که باید دقیق شناخته شوند.
ذخیره توکن در کوکی (HttpOnly Cookie)
مزایا:
- HttpOnly بودن کوکی باعث میشود جاوااسکریپت نتواند مستقیماً به کوکی دسترسی داشته باشد → کاهش ریسک دزدیده شدن توکن توسط XSS.
- مرورگر به صورت خودکار کوکیهای مرتبط را در هر درخواست به سرور ارسال میکند → نیازی به مدیریت دستی در فرانت نیست.
معایب:
- اگر کوکی با SameSite=None یا بدون محدودیت ست شود، در معرض حملات CSRF قرار میگیرد.
- کنترل دستی بر ارسال توکن در هر درخواست کمتر است.
خطرات امنیتی:
- اگر سایت از SameSite=Lax یا SameSite=Strict استفاده نکند و تدابیر ضد-CSRF اعمال نشود، مهاجم میتواند از طریق یک فرم یا درخواست از سایت قربانی، درخواستهای جعلی به سرور ارسال کند.
ذخیره توکن در Authorization Header
مزایا:
- توکن تحت کنترل کامل فرانتاند قرار میگیرد → فقط وقتی بخواهیم درخواست بدهیم، هدر Authorization ست میشود.
- چون مرورگر هدر Authorization را اتوماتیک اضافه نمیکند، ریسک CSRF عملاً حذف میشود.
معایب:
- توکن در حافظهی کلاینت (مثلاً localStorage یا memory) قابل دسترسی است → در صورت وجود آسیبپذیری XSS، مهاجم میتواند آن را سرقت کند.
- نیاز به مدیریت دستی برای ست کردن هدر در هر درخواست.
خطرات امنیتی:
- در صورت وجود XSS، مهاجم میتواند کدی اجرا کند که توکن را از حافظهی مرورگر استخراج و به سرور خود ارسال کند.
XSS چطور تهدید ایجاد میکند؟
XSS (Cross-site Scripting) به مهاجم این اجازه را میدهد که اسکریپتهای مخرب خود را روی سایت شما اجرا کند.
وقتی توکن در localStorage یا در متغیرهای جاوااسکریپت نگهداری شود:
- اسکریپتهای آلوده میتوانند مستقیماً توکن را بردارند و به بیرون ارسال کنند.
- این سرقت میتواند به دسترسی کامل به حساب کاربری قربانی منجر شود.
استفاده از HttpOnly Cookie مانع از دسترسی جاوااسکریپت به توکن میشود و ریسک XSS را برای توکن کاهش میدهد.
CSRF چطور تهدید ایجاد میکند؟
CSRF (Cross-site Request Forgery) حملهای است که کاربر را بدون اطلاع، مجبور به ارسال درخواست ناخواسته به سرور میکند.
وقتی از کوکی برای ذخیره توکن استفاده میکنیم:
- مرورگر به طور خودکار کوکیها را در درخواستها ضمیمه میکند، بدون توجه به اینکه درخواست واقعی است یا جعلی.
- اگر تدابیر محافظتی مانند SameSite Strict یا CSRF Token اعمال نشود، سرور نمیتواند تشخیص دهد درخواست از یک صفحه معتبر آمده یا خیر.
وقتی از Authorization Header استفاده شود:
- چون مرورگر به طور خودکار Authorization Header را اضافه نمیکند، حمله CSRF عملاً غیرممکن میشود.
بهترین راهکارها و توصیهها
برای ایمن نگه داشتن سیستم احراز هویت:
-
اگر از کوکی استفاده میکنید:
HttpOnly
وSecure
را فعال کنید.SameSite=Strict
یا حداقلSameSite=Lax
را تنظیم کنید.- برای درخواستهای حساس از CSRF Token استفاده کنید.
-
اگر از Authorization Header استفاده میکنید:
- ورودیهای کاربر را به طور کامل sanitize کنید.
- از Content Security Policy (CSP) مناسب استفاده کنید.
- توکنها عمر کوتاه داشته باشند و مکانیزم Refresh Token امن وجود داشته باشد.
-
در هر صورت:
- توکنها را طولانیمدت نگه ندارید.
- در صورت نیاز، Session Expiry و Invalidate Token در سرور را پیادهسازی کنید.
جمعبندی
هیچ روشی مطلقاً بیخطر نیست (در زمان نگارش این مقاله، هیچ روش کاملاً بیخطری برای ذخیره و انتقال توکن وجود ندارد و نباید دنبال امنیت مطلق بود؛ هدف این است که روش انتخابی را بشناسیم و ریسکهای آن را مدیریت کنیم).
انتخاب بین کوکی HttpOnly و Authorization Header بستگی به مدل پروژه، میزان حساسیت دادهها و نوع تهدیداتی دارد که پروژه در معرض آن است.
مهم این است که فارغ از روشی که انتخاب میکنیم، تدابیر امنیتی مناسب را برای آن در نظر بگیریم و همیشه نسبت به تهدیدات جدید بهروز بمانیم.