مدیریت session در Laravel و PHP
مدیریت session ها در PHP به صورت پیش فرض وجود دارد. اما لاراول (Laravel) از روش خود برای کار با session استفاده می کند. در این مقاله، ما هر دو روش را توضیح می دهیم.
قبل از اینکه روش کار session در PHP و لاراول را توضیح دهیم، اجازه دهید تا با هم مرور کنیم که session واقعا چیست.
تفاوت بین session و cookie چیست؟
برنامه ی شما می تواند هرچه بخواهد روی cookie های کاربر ذخیره کند. برای مثال نام کاربری و اینکه کاربر در سایت log in کرده است. ذخیره ی این اطلاعات به صورت متن خام در cookie ایده ی بدی است، زیرا کاربر می تواند cookie های خود را تغییر دهد. بنابراین یک هکر می تواند در cookie بگوید که کاربر ادمین است و log in کرده است. برای جلوگیری از این آسیب پذیری ما فقط session_id
را در cookie ذخیره می کنیم و اطلاعات session روی سرور ذخیره می شود (این اطلاعات می تواند به صورت فایل، در دیتابیس و... ذخیره شود).
هر مرتبه که کاربر یک درخواست ارسال می کند، cookie ها نیز همراه با درخواست ارسال می شوند. سرور session_id
را از روی cookie می خواند و به داده های متناظر با این session_id
دسترسی پیدا می کند. این اطلاعات می تواند یک فایل هم نام با مقدار session_id
باشد که اطلاعات مربوط به این کاربر را نگهداری می کند.
شما می توانید درخواست خودتان را در inspection مرورگر خود (این پنجره با فشردن کلید F12 باز می شود)، در نوار network مشاهده کنید. در این قسمت شما کلید و مقدار تمام cookie های ارسال شده را می بینید.
همچنین شما می توانید در نوار application تمام کوکی های یک سایت را ببینید.
آیا همه ی سایت ها از session استفاده می کنند؟
خیر. برای مثال WordPress از session استفاده نمی کند. WordPress نام کاربر را به صورت hash شده در cookie ذخیره می کند، بنابراین شما نمی توانید به راحتی خود را کسی دیگر جا بزنید و برای مثال به عنوان ادمین log in کنید، چون نمی دانید که hash چگونه تولید شده است.
چگونه در PHP یک session ایجاد کنیم؟
PHP برای کار با session و مدیریت آن، توابع آماده ای دارد. شما به راحتی می توانید پس از فراخوانی تابع ()session_start
در کدتان، session را ایجاد کنید و اگر در درخواست، session_id
وجود داشته باشد از طریق آرایه ی SESSION_$
به اطلاعات session دسترسی پیدا کنید.
به صورت پیش فرض session ها در پوشه ی tmp
سرور شما (یا هر جایی که در php.ini
تنظیم کنید) ذخیره می شوند.
یک session دو طول عمر دارد. یکی طول عمر فایل session روی سرور و دیگری طول عمر cookie ای که session_id
را نگهداری می کند، که روی سیستم کاربر است.
امکان اینکه شما تعیین کنید session چه موقع از روی سرور پاک شود به صورت دقیق وجود ندارد. اما شما می توانید یک زمان مشخص کنید که پس از آن بازیافت کننده ی حافظه (garbage collector) بتواند آن را حذف کند. این زمان می تواند با تعیین مقدار session.gc_maxlifetime مشخص شود. این پارامتر مشخص می کند که پس از چند ثانیه داده ی session به عنوان زباله، تلقی شده و پتانسیل حذف شدن به وسیله ی بازیافت کننده ی حافظه را دارد. بازیافت کننده ی حافظه ممکن است در شروع ()session_start
شروع به کار کند و session های منقضی شده را پاک کند. احتمال اجرا شدن بازیافت کننده ی حافظه برای session ها از تقسیم پارامتر session.gc_probability بر session.gc_divisor محاسبه می شود. این پارامتر ها در php.ini
قابل تنظیم هستند.
طول عمر cookie را می توان با تنظیم پارامتر session.cookie.lifetime مشخص کرد. این مقدار برای مرورگر کاربر ارسال می شود و پس از گذشتن آن، مرورگر cookie را حذف می کند. مقدار پیش فرض آن ۰ است که در این حالت به محض بسته شدن مرورگر cookie پاک می شود.
به طور پیش فرض PHP session id
در کلید PHPSESSID نگهداری می شود. همانطور که گفته شد اگر طول عمر cookie برابر با ۰ قرار داده شده باشد، پس از بستن مرورگر، cookie پاک می شود. همچنین این حالت در ابزار بررسی سایت ها به این صورت نمایش داده می شود که، مقدار ستون Expires / Max-Age
برابر با Session
قرار می گیرد.
لاراول چگونه session ها را مدیریت می کند؟
لاراول از session های PHP استفاده نمی کند. در عوض لاراول چند درایور مختلف برای مدیریت session ها را پشتیبانی می کند.
در حالی که تابع های موجود در PHP با زبان C نوشته شده اند، کدهای مدیریت session در لاراول به صورت کامل با PHP نوشته شده اند. همچنین به جای انجام تنظیمات مربوط به session در فایل php.ini، شما می توانید در لاراول درون فایل config/session.php
به این تنظیمات دسترسی داشته باشید.
لاراول از درایورهای زیر برای ذخیره کردن session ها استفاده می کند:
- دیتابیس (Database)
- فایل (File)
- Cookie
- memcache
- آرایه ی PHP
- AWS DynamoDB
اینکه لاراول از کدام درایور استفاده کند را شما می توانید در فایل .env
روبروی کلید SESSION_DRIVER
مشخص کنید.
درایور cookie
تمام اطلاعات را به صورت hash شده درون cookie
نگهداری می کند. این حالت مشابه با WordPress است و هیچ داده ای سمت سرور نگهداری نمی شود.
درایور file برای هر کاربر یک فایل ایجاد می کند و اطلاعات مربوط به کاربر را درون آن نگهداری می کند. به صورت پیش فرض فایل ها درون پوشه ی /storage/framework/sessions/
ذخیره می شوند، اما شما می توانید درون فایل config/session.php
آن را تغییر دهید.
'files' => storage_path('framework/sessions'),
در لاراول چگونه طول عمر session را مشخص کنیم؟
شما می توانید مشخص کنید که لاراول بعد از چه مدت یک session را پاک کند. دقت کنید که این پارامتر حداقل عمر session را تضمین می کند. همچنین شما می توانید با قرار دادن مقدار true برای کلید ‘expire_on_close
’ مشخص کنید که cookie ای که session_id
را روی سیستم کاربر نگهداری می کند پس از بستن مرورگر پاک شود.
'lifetime' => 120,
'expire_on_close' => false,
نام cookie ای که session_id
را نگهداری می کند به صورت {session_ نام برنامه ی شما}
است. مانند باقی پارامتر های session
، شما می توانید درون فایل تنظیمات session
، آن را تغییر دهید.
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
),
بازیافت کننده ی حافظه در لاراول
در هر درخواستی که به لاراول می رسد، شانس اینکه بازیافت کننده ی حافظه ی لاراول اجرا شود، وجود دارد. هنگامی که بازیافت کننده ی حافظه در لاراول اجرا می شود، تمام session هایی که عمرشان تمام شده است، حذف می شوند.
بازیافت کننده ی حافظه، یک الگوی معروف است و همان طور که توضیح دادیم PHP نیز از آن برای session ها استفاده می کند. بازیافت کننده در PHP به زبان C نوشته شده است در حالی که لاراول آن را با زبان PHP توسعه داده است.
بازیافت کننده ی حافظه ی لاراول در session middleware اجرا می شود:
protected function collectGarbage(Session $session)
{
$config = $this->manager->getSessionConfig();
// Here we will see if this request hits the
// garbage collection lottery by hitting
// the odds needed to perform garbage collection
//on any given request. If we do
// hit it, we'll call this handler to let it delete
// all the expired sessions.
if ($this->configHitsLottery($config)) {
$session->getHandler()
->gc($this->getSessionLifetimeInSeconds());
}
}
در نتیجه ی این روش اگر هیچ کسی به سایت شما درخواست ندهد، هیچ وقت بازیافت کننده ی حافظه اجرا نمی شود و فایل های session شما پاک نمی شوند.
به صورت پیش فرض احتمال اینکه در لاراول، بازیافت کننده ی حافظه اجرا شود، ۲ درصد است. در واقع اگر سایت شما ۱۰۰ درخواست دریافت کند، به طور حدودی در ۲ درخواست عملیات بازیافت حافظه صورت گرفته است. شما می توانید این احتمال را در فایل تنظیمات session تغییر دهید.
'lottery' => [2, 100],
در این مقاله شیوه ی تفاوت مدیریت session ها توسط لاراول با PHP را شرح دادیم و با هر دو فرایند آشنا شدیم. امیدوارم این مقاله برای شما مفید بوده باشد. نظرات و سوال هایتان را در قسمت نظرات با ما در میان بگذارید.
منبع:
https://iwasherefirst2.medium.com/how-do-laravel-sessions-work-7b65d74a79a6