Session در مقابل Token — احراز هویت Laravel برای وب، SPA و موبایل
کی session cookie و کی Bearer token؟ مقایسه امنیت، مقیاس و معماری برای monolith، SPA و API موبایل.
انتخاب session یا token در Laravel بیشتر از «کدام مد روز است» به نوع کلاینت، مرز اعتماد و چرخه عمر نشست وابسته است. اشتباه رایج: گذاشتن Bearer روی Blade سنتی بدون درک CSRF، یا انتظار session cookie از اپ native موبایل. این مقاله تصمیم session-versus-token را روشن میکند؛ راهاندازی عملی Sanctum در Sanctum API Auth و MFA در احراز هویت دو مرحلهای است.
Session-based چگونه کار میکند؟
کاربر وارد میشود → سرور شناسه نشست را در cookie (معمولاً رمزشده/امضاشده) میگذارد → مرورگر در requestهای بعدی cookie را میفرستد → Laravel وضعیت را از store (file، database، Redis و …) میخواند. این مدل stateful است: سرور وضعیت login را نگه میدارد.
مناسب: اپلیکیشن first-party مرورگر، Blade monolith، پنل ادمین، starterهایی مثل Breeze.
- خروج = باطل کردن session روی سرور (revoke نسبتاً فوری)
- در فرمهای سنتی، محافظت CSRF بخشی از مدل امنیتی cookie است
- با چند سرور، store مشترک (مثلاً Redis) معمولاً لازم میشود
Token / Bearer چگونه فرق دارد؟
کلاینت پس از login یک token میگیرد و آن را در Authorization: Bearer … میفرستد. سرور token را (مثلاً در جدول personal access tokens سنکتوم) بررسی میکند. کلاینت غیرمرورگر session cookie را مثل مرورگر مدیریت نمیکند؛ بنابراین token برای موبایل و API جدا رایج است.
«Stateless» مطلق نیست: بسیاری پیادهسازیها (از جمله Sanctum personal tokens) هنوز ردی در دیتابیس دارند تا revoke و abilities ممکن باشد.
جدول تصمیم
| معیار | Session (cookie) | Bearer token |
|---|---|---|
| کلاینت | مرورگر same-site / first-party | موبایل، سرویس ثالث، SPA جدا از دامنه |
| CSRF | برای cookie session معمولاً لازم | با Bearer در header معمولاً مدل CSRF کوکی اعمال نمیشود |
| خروج / قطع دسترسی | invalidate session | حذف یا expire کردن token |
| ذخیره سمت کلاینت | cookie (ترجیحاً HttpOnly) | حافظه امن پلتفرم؛ نه URL و نه localStorage بیمحافظ |
| Scale افقی | session store مشترک | lookup token + کش در صورت نیاز |
امنیت و چرخه عمر — بدون شعار مطلق
- نه session و نه token بهتنهایی «امنیت کامل» نیستند؛ XSS، فیشینگ و سرقت دستگاه هر دو را تهدید میکند
- token در URL یا لاگ درخواست ممنوع است
- در مرورگر، گذاشتن token بلندمدت در localStorage در برابر XSS آسیبپذیرتر از cookie HttpOnly است
- انقضا، چرخش و revoke را عمداً طراحی کنید؛ «token ابدی» ضدالگو است
- مجوز بعد از احراز هویت جداست — Policy و Authorization
SPA روی همان سایت — Sanctum stateful
اگر فرانت (Vue/React) و API روی دامنه/سابدامنه هماعتماد first-party هستند، Sanctum میتواند با cookie + CSRF شبیه session وب کار کند. این «token برای همهچیز» نیست؛ مدل cookie است با DX بهتر برای SPA. جزئیات پیادهسازی: راهنمای Sanctum.
موبایل و یکپارچگی ثالث
اپ native معمولاً Bearer (یا طرح مشابه) میخواهد. توکن را در ذخیره امن سیستمعامل نگه دارید، scope/ability محدود بدهید و مسیر refresh را مشخص کنید. برای وب ادمین همان پروژه، session همزمان روی یک User model کاملاً رایج و سالم است.
JWT چطور؟
Laravel بهصورت پیشفرض Sanctum را برای بسیاری سناریوهای first-party پیشنهاد میکند. JWT خودامضا میتواند revoke را سختتر کند مگر blacklist/versioning اضافه کنید. اگر JWT میآورید، چرخه expire/refresh و ابطال را خودتان طراحی کنید — معجزه امنیتی خودکار نیست.
تنظیمهای مرتبط در .env
SESSION_DRIVER=redis
SESSION_DOMAIN=.example.com
SANCTUM_STATEFUL_DOMAINS=app.example.com
مقدارها را با دامنه واقعی و محیط (local/production) هماهنگ کنید — راهنمای env.
تصورات نادرست رایج
- «همه APIها باید Bearer باشند» — API مرورگر first-party میتواند cookie/session باشد
- «Token همیشه امنتر از session است» — بستگی به ذخیره کلاینت و تهدید XSS دارد
- «Cookie یعنی ناامن» — با پرچمهای درست و CSRF، مدل استاندارد وب است
- «Logout در token لازم نیست» — بدون revoke، سرقت token تا انقضا معتبر میماند
جمعبندی
مرورگر first-party → معمولاً session/cookie. کلاینت جدا و موبایل → معمولاً Bearer با مدیریت عمر و ذخیره امن. SPA همدامنه → اغلب Sanctum stateful. انتخاب را از کلاینت و مرز اعتماد شروع کنید، نه از مد روز.