Sessions

CakePHP provides a wrapper and suite of utility features on top of PHP’s nativesession extension. Sessions allow you to identify unique users acrossrequests and store persistent data for specific users. Unlike Cookies, sessiondata is not available on the client side. Usage of $_SESSION is generallyavoided in CakePHP, and instead usage of the Session classes is preferred.

Session Configuration

Session configuration is generally defined in /config/app.php. The availableoptions are:

  • Session.timeout - The number of minutes before CakePHP’s sessionhandler expires the session.
  • Session.defaults - Allows you to use the built-in default sessionconfigurations as a base for your session configuration. See below for thebuilt-in defaults.
  • Session.handler - Allows you to define a custom session handler. The coredatabase and cache session handlers use this. See below for additionalinformation on Session handlers.
  • Session.ini - Allows you to set additional session ini settings for yourconfig. This combined with Session.handler replace the custom sessionhandling features of previous versions
  • Session.cookie - The name of the cookie to use. Defaults to ‘CAKEPHP’.
  • Session.cookiePath - The url path for which session cookie is set. Maps tothe session.cookie_path php.ini config. Defaults to base path of app.

CakePHP’s defaults session.cookie_secure to true, when your applicationis on an SSL protocol. If your application serves from both SSL and non-SSLprotocols, then you might have problems with sessions being lost. If you needaccess to the session on both SSL and non-SSL domains you will want to disablethis:

  1. Configure::write('Session', [
  2. 'defaults' => 'php',
  3. 'ini' => [
  4. 'session.cookie_secure' => false
  5. ]
  6. ]);

The session cookie path defaults to app’s base path. To change this you can usethe session.cookie_path ini value. For example if you want your session topersist across all subdomains you can do:

  1. Configure::write('Session', [
  2. 'defaults' => 'php',
  3. 'ini' => [
  4. 'session.cookie_path' => '/',
  5. 'session.cookie_domain' => '.yourdomain.com'
  6. ]
  7. ]);

By default PHP sets the session cookie to expire as soon as the browser isclosed, regardless of the configured Session.timeout value. The cookietimeout is controlled by the session.cookie_lifetime ini value and can beconfigured using:

  1. Configure::write('Session', [
  2. 'defaults' => 'php',
  3. 'ini' => [
  4. // Invalidate the cookie after 30 minutes without visiting
  5. // any page on the site.
  6. 'session.cookie_lifetime' => 1800
  7. ]
  8. ]);

The difference between Session.timeout and the session.cookie_lifetimevalue is that the latter relies on the client telling the truth about thecookie. If you require stricter timeout checking, without relying on what theclient reports, you should use Session.timeout.

Please note that Session.timeout corresponds to the total time ofinactivity for a user (i.e. the time without visiting any page where the sessionis used), and does not limit the total amount of minutes a user can stayon the site.

Built-in Session Handlers & Configuration

CakePHP comes with several built-in session configurations. You can either usethese as the basis for your session configuration, or you can create a fullycustom solution. To use defaults, simply set the ‘defaults’ key to the name ofthe default you want to use. You can then override any sub setting by declaringit in your Session config:

  1. Configure::write('Session', [
  2. 'defaults' => 'php'
  3. ]);

The above will use the built-in ‘php’ session configuration. You could augmentpart or all of it by doing the following:

  1. Configure::write('Session', [
  2. 'defaults' => 'php',
  3. 'cookie' => 'my_app',
  4. 'timeout' => 4320 // 3 days
  5. ]);

The above overrides the timeout and cookie name for the ‘php’ sessionconfiguration. The built-in configurations are:

  • php - Saves sessions with the standard settings in your php.ini file.
  • cake - Saves sessions as files inside tmp/sessions. This is agood option when on hosts that don’t allow you to write outside your own homedir.
  • database - Use the built-in database sessions. See below for moreinformation.
  • cache - Use the built-in cache sessions. See below for more information.

Session Handlers

Session handlers can also be defined in the session config array. By definingthe ‘handler.engine’ config key, you can name the class name, or providea handler instance. The class/object must implement thenative PHP SessionHandlerInterface. Implementing this interface will allowSession to automatically map the methods for the handler. Both the coreCache and Database session handlers use this method for saving sessions.Additional settings for the handler should be placed inside the handler array.You can then read those values out from inside your handler:

  1. 'Session' => [
  2. 'handler' => [
  3. 'engine' => 'DatabaseSession',
  4. 'model' => 'CustomSessions'
  5. ]
  6. ]

The above shows how you could setup the Database session handler with anapplication model. When using class names as your handler.engine, CakePHP willexpect to find your class in the Http\Session namespace. For example, ifyou had an AppSessionHandler class, the file should besrc/Http/Session/AppSessionHandler.php, and the class name should beApp\Http\Session\AppSessionHandler. You can also use session handlersfrom inside plugins. By setting the engine to MyPlugin.PluginSessionHandler.

Database Sessions

If you need to use a database to store your session data, configure as follows:

  1. 'Session' => [
  2. 'defaults' => 'database'
  3. ]

This configuration requires a database table, having this schema:

  1. CREATE TABLE `sessions` (
  2. `id` char(40) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,
  3. `created` datetime DEFAULT CURRENT_TIMESTAMP, -- Optional
  4. `modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- Optional
  5. `data` blob DEFAULT NULL, -- for PostgreSQL use bytea instead of blob
  6. `expires` int(10) unsigned DEFAULT NULL,
  7. PRIMARY KEY (`id`)
  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

You can find a copy of the schema for the sessions table in the application skeleton in config/schema/sessions.sql.

You can also use your own Table class to handle the saving of the sessions:

  1. 'Session' => [
  2. 'defaults' => 'database',
  3. 'handler' => [
  4. 'engine' => 'DatabaseSession',
  5. 'model' => 'CustomSessions'
  6. ]
  7. ]

The above will tell Session to use the built-in ‘database’ defaults, andspecify that a Table called CustomSessions will be the delegate for savingsession information to the database.

Cache Sessions

The Cache class can be used to store sessions as well. This allows you to storesessions in a cache like APCu, or Memcached. There are some caveats tousing cache sessions, in that if you exhaust the cache space, sessions willstart to expire as records are evicted.

To use Cache based sessions you can configure you Session config like:

  1. Configure::write('Session', [
  2. 'defaults' => 'cache',
  3. 'handler' => [
  4. 'config' => 'session'
  5. ]
  6. ]);

This will configure Session to use the CacheSession class as thedelegate for saving the sessions. You can use the ‘config’ key which cacheconfiguration to use. The default cache configuration is 'default'.

Setting ini directives

The built-in defaults attempt to provide a common base for sessionconfiguration. You may need to tweak specific ini flags as well. CakePHPexposes the ability to customize the ini settings for both defaultconfigurations, as well as custom ones. The ini key in the session settings,allows you to specify individual configuration values. For example you can useit to control settings like session.gc_divisor:

  1. Configure::write('Session', [
  2. 'defaults' => 'php',
  3. 'ini' => [
  4. 'session.cookie_name' => 'MyCookie',
  5. 'session.cookie_lifetime' => 1800, // Valid for 30 minutes
  6. 'session.gc_divisor' => 1000,
  7. 'session.cookie_httponly' => true
  8. ]
  9. ]);

Creating a Custom Session Handler

Creating a custom session handler is straightforward in CakePHP. In thisexample we’ll create a session handler that stores sessions both in the Cache(APC) and the database. This gives us the best of fast IO of APC,without having to worry about sessions evaporating when the cache fills up.

First we’ll need to create our custom class and put it insrc/Http/Session/ComboSession.php. The class should looksomething like:

  1. namespace App\Http\Session;
  2.  
  3. use Cake\Cache\Cache;
  4. use Cake\Core\Configure;
  5. use Cake\Http\Session\DatabaseSession;
  6.  
  7. class ComboSession extends DatabaseSession
  8. {
  9. public $cacheKey;
  10.  
  11. public function __construct()
  12. {
  13. $this->cacheKey = Configure::read('Session.handler.cache');
  14. parent::__construct();
  15. }
  16.  
  17. // Read data from the session.
  18. public function read($id)
  19. {
  20. $result = Cache::read($id, $this->cacheKey);
  21. if ($result) {
  22. return $result;
  23. }
  24. return parent::read($id);
  25. }
  26.  
  27. // Write data into the session.
  28. public function write($id, $data)
  29. {
  30. Cache::write($id, $data, $this->cacheKey);
  31. return parent::write($id, $data);
  32. }
  33.  
  34. // Destroy a session.
  35. public function destroy($id)
  36. {
  37. Cache::delete($id, $this->cacheKey);
  38. return parent::destroy($id);
  39. }
  40.  
  41. // Removes expired sessions.
  42. public function gc($expires = null)
  43. {
  44. return Cache::clear(true, $this->cacheKey) && parent::gc($expires);
  45. }
  46. }

Our class extends the built-in DatabaseSession so we don’t have to duplicateall of its logic and behavior. We wrap each operation witha Cake\Cache\Cache operation. This lets us fetch sessions fromthe fast cache, and not have to worry about what happens when we fill the cache.Using this session handler is also easy. In config/app.php make the sessionblock look like:

  1. 'Session' => [
  2. 'defaults' => 'database',
  3. 'handler' => [
  4. 'engine' => 'ComboSession',
  5. 'model' => 'Session',
  6. 'cache' => 'apc'
  7. ]
  8. ],
  9. // Make sure to add a apc cache config
  10. 'Cache' => [
  11. 'apc' => ['engine' => 'Apc']
  12. ]

Now our application will start using our custom session handler for reading andwriting session data.

  • class Session

Accessing the Session Object

You can access the session data any place you have access to a request object.This means the session is accessible from:

  • Controllers
  • Views
  • Helpers
  • Cells
  • Components

In addition to the basic session object, you can also use theCake\View\Helper\SessionHelper to interact with the session inyour views. A basic example of session usage would be:

  1. $name = $this->getRequest()->getSession()->read('User.name');
  2.  
  3. // If you are accessing the session multiple times,
  4. // you will probably want a local variable.
  5. $session = $this->getRequest()->getSession();
  6. $name = $session->read('User.name');

Reading & Writing Session Data

  • Session::read($key)

You can read values from the session using Hash::extract()compatible syntax:

  1. $session->read('Config.language');
  • Session::write($key, $value)

$key should be the dot separated path you wish to write $value to:

  1. $session->write('Config.language', 'en');

You may also specify one or multiple hashes like so:

  1. $session->write([
  2. 'Config.theme' => 'blue',
  3. 'Config.language' => 'en',
  4. ]);
  • Session::delete($key)

When you need to delete data from the session, you can use delete():

  1. $session->delete('Some.value');
  • static Session::consume($key)

When you need to read and delete data from the session, you can useconsume():

  1. $session->consume('Some.value');
  • Session::check($key)

If you want to see if data exists in the session, you can use check():

  1. if ($session->check('Config.language')) {
  2. // Config.language exists and is not null.
  3. }

Destroying the Session

  • Session::destroy()

Destroying the session is useful when users log out. To destroy a session, usethe destroy() method:

  1. $session->destroy();

Destroying a session will remove all serverside data in the session, but willnot remove the session cookie.

Rotating Session Identifiers

  • Session::renew()

While AuthComponent automatically renews the session id when users login andlogout, you may need to rotate the session id’s manually. To do this use therenew() method:

  1. $session->renew();

Flash Messages

Flash messages are small messages displayed to end users once. They are oftenused to present error messages, or confirm that actions took place successfully.

To set and display flash messages you should useFlashComponent andFlashHelper