23 Juil, 2020

Les cookies sous CakePHP 4

Écriture, lecture et suppression de cookies sous CakePHP4.

Le composant Cookie ayant été retiré de la version 4 de CakePHP, nous allons voir dans cet article les méthodes à utiliser afin de gérer des cookies.

Créer, lire et supprimer des cookies

Nous allons utiliser la classe Cookie

use Cake\Http\Cookie\Cookie;

Pour instancier votre cookie vous pouvez utiliser le constructeur en y intégrant tous vos arguments ou bien utiliser les méthodes de la classe :

// Tous les arguments dans le constructeur
$cookie = new Cookie(
    'mon_cookie', // nom
    '1', // valeur
    new DateTime('+1 year'), // expiration
    '/', // chemin
    'example.com', // domaine
    false, // https seulement
    true // via http seulement
);

// Méthodes de la classe
$cookie = (new Cookie('mon_cookie'))
    ->withValue('1')
    ->withExpiry(new DateTime('+1 year'))
    ->withPath('/')
    ->withDomain('example.com')
    ->withSecure(false)
    ->withHttpOnly(true);

Une fois votre cookie instancié, vous pouvez l’ajouter en réponse afin de le créer via la méthode withCookie.

$this->response = $this->response->withCookie($cookie);

Pour lire la valeur de votre cookie vous pouvez utiliser la méthode getCookie de la requête :

// Rend null si le cookie n'existe pas
$value = $this->request->getCookie('mon_cookie');

Utilisez la méthode withExpiredCookie pour faire expirer votre cookie et ainsi le supprimer du navigateur :

$this->response = $this->response->withExpiredCookie(new Cookie('mon_cookie'));

Si vous souhaitez créer plusieurs cookies en même temps vous pouvez utiliser une collection de cookies :

class Cake\Http\Cookie\CookieCollection;
// Création d'une collection de cookies
$cookies = new CookieCollection([$cookie]);

// Ajoute un cookie à la collection
$cookies = $cookies->add($cookie);

// Récupère un cookie de la collection
$cookies = $cookies->get('mon_cookie');

// Supprime un cookie de la collection
$cookies = $cookies->remove('mon_cookie');

Afin de créer vos cookies vous pouvez utiliser la méthode withCookieCollection :

$this->response = $this->response->withCookieCollection($cookies);

Cryptez des cookies

Pour des raisons de sécurité, il est important de crypter vos cookies et ainsi rendre leur lecture « impossible » hors de votre application.

Pour cela rendez-vous dans le fichier src/Application.php et importez la classe suivante :

use Cake\Http\Middleware\EncryptedCookieMiddleware;

La classe EncryptedCookieMiddleware prend en premier paramètre un tableau de cookies qui sont donc les cookies que vous souhaitez crypter, et en second paramètre la clé de cryptage.

Dans la méthode middleware utilisez cette classe et ajoutez la à la file d’attente des middlewares :

$cookies = new EncryptedCookieMiddleware(
    ['mon_cookie'], // cookies à crypter
    Configure::read('Security.cookieKey') // clé de cryptage
);

$middlewareQueue->add($cookies);   

Il est conseillé d’utiliser une clé de cryptage unique. Ici nous l’avons créée dans app.php :

'Security' => [
    'salt' => env('SECURITY_SALT'),
    'cookieKey' => '...Votre clé de cryptage...'
],

En conclusion

Le composant Cookie désormais retiré de CakePHP, permettait de manipuler simplement les cookies de nos applications. Il faut dorénavant soit même développer les différentes étapes : instanciation du cookie, génération et expiration du cookie via $this->response ou encore lecture à l’aide de la méthode $this->request->getCookie(). De même, anciennement automatique, le cryptage de la valeur du cookie doit s’effectuer au niveau des middlewares à l’aide d’une clé de cryptage spécialement créée ainsi que la liste définie des cookies à crypter.