2017 © Pedro PelĂĄez
 

library psr7-session

Storageless PSR-7 Session support

image

ocramius/psr7-session

Storageless PSR-7 Session support

  • Wednesday, September 21, 2016
  • by Ocramius
  • Repository
  • 29 Watchers
  • 267 Stars
  • 3,458 Installations
  • PHP
  • 1 Dependents
  • 0 Suggesters
  • 20 Forks
  • 9 Open issues
  • 7 Versions
  • 0 % Grown

The README.md

PSR-7 Storage-less HTTP Sessions

Build Status Scrutinizer Code Quality Code Coverage Packagist Packagist, (*1)

PSR7Session is a PSR-7 and PSR-15 compatible middleware that enables session without I/O usage in PSR-7 based applications., (*2)

Proudly brought to you by ocramius, malukenho and lcobucci., (*3)

Installation

composer require psr7-sessions/storageless

Usage

You can use the PSR7Sessions\Storageless\Http\SessionMiddleware in any PSR-15 compatible middleware., (*4)

In a mezzio/mezzio application, this would look like following:, (*5)

$app = new \Mezzio\Application(/* ... */);

$app->pipe(\PSR7Sessions\Storageless\Http\SessionMiddleware::fromSymmetricKeyDefaults(
    'mBC5v1sOKVvbdEitdSBenu59nfNfhwkedkJVNabosTw=', // replace this with a key of your own (see docs below)
    1200 // 20 minutes
));

After this, you can access the session data inside any middleware that has access to the Psr\Http\Message\ServerRequestInterface attributes:, (*6)

$app->get('/get', function (ServerRequestInterface $request, ResponseInterface $response) : ResponseInterface {
    /* @var \PSR7Sessions\Storageless\Session\Data $session */
    $session = $request->getAttribute(SessionMiddleware::SESSION_ATTRIBUTE);
    $session->set('counter', $session->get('counter', 0) + 1);

    $response
        ->getBody()
        ->write('Counter Value: ' . $session->get('counter'));

    return $response;
});

You can do this also in asynchronous contexts and long running processes, since no super-globals nor I/O are involved., (*7)

It is recommended that you use a key with lots of entropy, preferably generated using a cryptographically secure pseudo-random number generator (CSPRNG). You can use the CryptoKey tool to do this for you., (*8)

Note that you can also use asymmetric keys by using either the PSR7Sessions\Storageless\Http\SessionMiddleware constructor or the named constructor PSR7Sessions\Storageless\Http\SessionMiddleware::fromAsymmetricKeyDefaults(), (*9)

Examples

Simply browse to the examples directory in your console, then run, (*10)

php -S localhost:9999 index.php

Then try accessing http://localhost:9999: you should see a counter that increases at every page refresh, (*11)

WHY?

In most PHP+HTTP related projects, ext/session serves its purpose and allows us to store server-side information by associating a certain identifier to a visiting user-agent., (*12)

What is the problem with ext/session?

This is all fair and nice, except for:, (*13)

  • relying on the $_SESSION superglobal
  • relying on the shutdown handlers in order to "commit" sessions to the storage
  • having a huge limitation of number of active users (due to storage)
  • having a lot of I/O due to storage
  • having serialized data cross different processes (PHP serializes and de-serializes $_SESSION for you, and there are security implications)
  • having to use a centralized storage for setups that scale horizontally
  • having to use sticky sessions (with a "smart" load-balancer) when the storage is not centralized
  • not designed to be used for multiple dispatch cycles

What does this project do?

This project tries to implement storage-less sessions and to mitigate the issues listed above., (*14)

Assumptions

  • your sessions are fairly small and contain only few identifiers and some CSRF tokens. Small means < 400 bytes
  • data in your session is JsonSerializable or equivalent
  • data in your session is freely readable by the client

How does it work?

Session data is directly stored inside a session cookie as a JWT token., (*15)

This approach is not new, and is commonly used with Bearer tokens in HTTP/REST/OAuth APIs., (*16)

In order to guarantee that the session data is not modified, that the client can trust the information and that the expiration date is mutually agreed between server and client, a JWT token is used to transmit the information., (*17)

The JWT token is always signed to ensure that the user-agent is never able to manipulate the session. Both symmetric and asymmetric keys are supported for signing/verifying tokens., (*18)

Advantages

  • no storage required
  • no sticky sessions required (any server having a copy of the private or public keys can generate sessions or consume them)
  • can transmit cleartext information to the client, allowing it to share some information with the server (a standard example is about sharing the "username" or "user-id" in a given session)
  • can transmit encrypted information to the client, allowing server-only consumption of the information
  • not affected by PHP serialization RCE attacks
  • not limited to PHP process scope: can have many sessions per process
  • no reliance on global state
  • when in a multi-server setup, you may allow read-only access to servers that only have access to public keys, while writes are limited to servers that have access to private keys
  • can be used over multiple dispatch cycles

Configuration options

Please refer to the configuration documentation., (*19)

Known limitations

Please refer to the limitations documentation., (*20)

Contributing

Please refer to the contributing notes., (*21)

License

This project is made public under the MIT LICENSE., (*22)

The Versions

21/09 2016
29/05 2016
31/12 2015