Laravel sessions vs PHP session
PHP comes with a native way to handle sessions. Laravel is using its own. This article explains how.
Before we start, let us recap what a session actually is:
Whats the difference between session and cookies again?
Your web application can store whatever it wants on the clients cookie. For example, the username and the information that the user is logged in. Now storing this information in the cookie as plain text is a bad idea, because every client can edit his cookies. Thus, a malicious person could just state in the cookie that he is a superadmin and logged in. In order to prevent that, there is usually only a session_id stored in the cookie. The session itself is a data structure on the server (could be stored as a file, in a database, in memory or other possibilities).
Every time a user sends a request all cookie values will be send along. On the server, the sessionId will be read from the cookie and can then access the associated session data on the server. This could be a file named by the sessionId that contains the information that the user is logged in.
You can check the request in your browser in the inspection window in the network tap. There you will see the all value-key pairs from your cookie, separated by a semicolon. You can find all stored cookies from a website in the storage tab.
So everyone uses sessions?
No. For instance, WordPress is not using sessions. Instead, it stores the username as a hashed value in the cookie, so you cannot easily login as another user, since you don’t know how the hash is created.
How to create a session in PHP?
PHP comes with native functions and options for session. You simple have to call session_start() in your script and then you can access the session data through the array $_SESSION.
By default, the sessions are stored in a tmp directory on your server (or whatever you have configured in the php.ini).
A session has two lifetimes. One is the the lifetime of the session file on the server, the other lifetime the cookie that stores the session id.
You cannot specify the time on which a session will be removed on the server, but you can specify a time at which it may gets removed by a garbage collector. This time can be set by session.gc_maxlifetime :
session.gc_maxlifetime
specifies the number of seconds after which data will be seen as ‘garbage’ and potentially cleaned up. Garbage collection may occur during session start (depending on session.gc_probability and session.gc_divisor).https://www.php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime
The cookie lifetime can be specified by:
session.cookie_lifetime
specifies the lifetime of the cookie in seconds which is sent to the browser. The value 0 means “until the browser is closed.” Defaults to0
.Note: The expiration timestamp is set relative to the server time, which is not necessarily the same as the time in the client’s browser.
https://www.php.net/manual/en/session.configuration.php#ini.session.cookie-lifetime
By default, the cookie name of the PHP session id will be called PHPSESSID. If the cookie lifetime is set to 0, the cookie will be removed when the browser is closed. In this case, the value in the Expires/Max-Age
column is set to Session.
How does Laravel manages its session?
Laravel is not using the PHP session driver. Instead, it came up with a wrapper and supports multiple session drivers.
The difference is, in PHP the above session methods and options have been written in C and are available as php native functions.
Laravel session on the other hand is purely written in PHP. Instead of customizing the sessions via php.ini
like session.gc_lifetime
etc, you can config your session in config/session.php
.
Storage drivers
Laravel overs different storage drivers for session:
- Database
- File
- Cookie
- memcache
- PHP array
- AWS dynamoDB
The storage driver can be specified in the config
'driver' => env('SESSION_DRIVER', 'file'),
A cookie session driver will store all information hashed in the cookie, just as WordPress. So nothing is stored on the server.
A file based driver will store create a file for every user in the folder /storage/framework/sessions/
by default. You may also specify a different location:
'files' => storage_path('framework/sessions'),
How to specify Laravel session duration?
The lifetime will set when the session files may be removed. The lifetime guarantees the minimum lifetime of a session.
'lifetime' => 120,'expire_on_close' => false,
If expire_on_close is set to true, the Expires/Max-Age
column from your cookie will be set to session, i.e. it will be removed when the browser closes.
If expire_on_close is set to false, the cookie lifetime will be set to current date increased by the specified lifetime. This means you find in your cookie an specific date in the Expires/Max-Age
column:
The default cookie name is laravel_session
but you can change it aswell:
'cookie' => env(
'SESSION_COOKIE',
str_slug(env('APP_NAME', 'laravel'), '_') . '_session'
),
What is Laravels Garbage Collector?
On every request, there is a given percentage that the garbage collector is executed. Only when the garbage collector is executed, all sessions that are older then their lifetime are removed.
The garbage collector is a known pattern and also used in native PHP session (see above session.gc_maxlifetime
). Laravel created its own garbage collector written as a PHP class, while on PHP session the garbage collector is written in C.
The Laravel garbage collector is executed in the 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());
}
}
It also means, if no body is requesting your website, then the garbage collector will never be executed and your session files won’t be removed.
The default probability that the garbage collector is executed is by 2%. This means, the probability that the garbage collector is executed within the first 50 requests is 64%, and withing the first 100 requests its 87%*. You also can customize the percentage:
'lottery' => [2, 100]
Will remember me work beyond session life time?
If a user enables the remember me option on login, then he will be logged in forever. This works by saving a user token into the clients cookie and in the users table. The values will be compered when the users opens the browser and the session is expired but a cookie is found. The users session will still last only for your specified lifetime. If his session is over, a new one will be created and the user is automatically be logged in.
Whats the difference between Laravel cache and Laravel session?
Laravel cache will store information globally for all users. The session is only available for one particular user.
So your news feed could be stored in Laravel cache with a lifetime for 24 hours(or depending how often you publish news) to prevent database requests on every page load. Where as the login status should be stored in the session and not in the cache, because its only relevant for one user.
*you can calculate that using Bernoulli. We have n=number of first requests, p=0.02 and we want to have at least one hit in the Bernoulli chain. If X is the sum of all the hits in our n requests, we have
P(X ≥ 1) = 1-P(X=0) = 1–(0.98)^n