مدیریت session در Laravel و PHP

مدیریت session در Laravel و PHP

مدیریت session در Laravel و PHP

مدیریت session ها در PHP به صورت پیش فرض وجود دارد. اما لاراول (Laravel) از روش خود برای کار با session استفاده می کند. در این مقاله، ما هر دو روش را توضیح می دهیم.

قبل از اینکه روش کار session در PHP و لاراول را توضیح دهیم، اجازه دهید تا با هم مرور کنیم که session واقعا چیست.

تفاوت بین session و cookie چیست؟

Session and 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 های ارسال شده را می بینید.

Cookie فرستاده شده همراه با درخواست

همچنین شما می توانید در نوار application تمام کوکی های یک سایت را ببینید.

Cookie ذخیره شده روی مرورگر

آیا همه ی سایت ها از 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 قرار می گیرد.

PHP 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,
Laravel Session روی مرورگر

نام 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

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