Nette Documentation Preview

syntax
Sessions
********
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Sessions

HTTP est un protocole sans état, mais presque toutes les applications ont besoin de conserver un état entre les requêtes, par exemple le contenu d'un panier d'achat. C'est précisément à cela que servent les sessions. Nous allons montrer :

  • comment utiliser les sessions
  • comment éviter les conflits de noms
  • comment définir l'expiration

Lors de l'utilisation des sessions, chaque utilisateur reçoit un identifiant unique appelé ID de session, qui est transmis dans un cookie. Celui-ci sert de clé pour les données de session. Contrairement aux cookies, qui sont stockés côté navigateur, les données de session sont stockées côté serveur.

Nous configurons la session dans la configuration, le choix de la durée d'expiration est particulièrement important.

La gestion de la session est assurée par l'objet Nette\Http\Session, auquel vous accédez en vous le faisant passer via l'injection de dépendances. Dans les presenters, il suffit d'appeler $session = $this->getSession().

Installation et prérequis

Démarrage de la session

Par défaut, Nette démarre automatiquement la session au moment où nous commençons à lire ou à écrire des données dedans. Manuellement, la session est démarrée à l'aide de $session->start().

PHP envoie lors du démarrage de la session des en-têtes HTTP affectant la mise en cache, voir session_cache_limiter, et éventuellement aussi un cookie avec l'ID de session. Il est donc nécessaire de toujours démarrer la session avant d'envoyer toute sortie au navigateur, sinon une exception sera levée. Si vous savez donc que la session sera utilisée pendant le rendu de la page, démarrez-la manuellement avant, par exemple dans le presenter.

En mode développeur, Tracy démarre la session car elle l'utilise pour afficher les barres avec les redirections et les requêtes AJAX dans la barre Tracy.

Sections

En PHP pur, le stockage des données de session est réalisé sous forme de tableau accessible via la variable globale $_SESSION. Le problème est que les applications sont généralement composées de nombreuses parties indépendantes les unes des autres, et si toutes n'ont qu'un seul tableau à leur disposition, tôt ou tard un conflit de noms se produira.

Nette Framework résout le problème en divisant tout l'espace en sections (objets Nette\Http\SessionSection). Chaque unité utilise alors sa propre section avec un nom unique et aucune collision ne peut plus se produire.

Nous obtenons la section de la session :

$section = $session->getSection('nom unique');

Dans le presenter, il suffit d'utiliser getSession() avec un paramètre :

// $this est un Presenter
$section = $this->getSession('nom unique');

On peut vérifier l'existence de la section avec la méthode $session->hasSection('nom unique').

Travailler avec la section elle-même est ensuite très facile à l'aide des méthodes set(), get() et remove() :

// écriture d'une variable
$section->set('userName', 'franta');

// lecture d'une variable, retourne null si elle n'existe pas
echo $section->get('userName');

// suppression d'une variable
$section->remove('userName');

Pour obtenir toutes les variables de la section, il est possible d'utiliser une boucle foreach :

foreach ($section as $key => $val) {
	echo "$key = $val";
}

Définition de l'expiration

Il est possible de définir une expiration pour des sections individuelles ou même des variables individuelles. Nous pouvons ainsi faire expirer la connexion de l'utilisateur après 20 minutes, tout en continuant à mémoriser le contenu du panier.

// la section expirera après 20 minutes
$section->setExpiration('20 minutes');

Pour définir l'expiration de variables individuelles, le troisième paramètre de la méthode set() est utilisé :

// la variable 'flash' expirera déjà après 30 secondes
$section->set('flash', $message, '30 seconds');

N'oubliez pas que la durée d'expiration de toute la session (voir configuration de session) doit être égale ou supérieure à la durée définie pour les sections ou variables individuelles.

L'annulation d'une expiration précédemment définie est réalisée avec la méthode removeExpiration(). La suppression immédiate de toute la section est assurée par la méthode remove().

Événements $onStart, $onBeforeWrite

L'objet Nette\Http\Session a des événements $onStart et $onBeforeWrite, vous pouvez donc ajouter des callbacks qui seront appelés après le démarrage de la session ou avant son écriture sur le disque et sa fermeture ultérieure.

$session->onBeforeWrite[] = function () {
	// nous écrivons les données dans la session
	$this->section->set('basket', $this->basket);
};

Gestion de la session

Aperçu des méthodes de la classe Nette\Http\Session pour la gestion de la session :

start(): void

Démarre la session.

isStarted(): bool

La session est-elle démarrée ?

close(): void

Termine la session. La session se termine automatiquement à la fin de l'exécution du script.

destroy(): void

Termine et supprime la session.

exists(): bool

La requête HTTP contient-elle un cookie avec l'ID de session ?

regenerateId(): void

Génère un nouvel ID de session aléatoire. Les données restent conservées.

getId(): string

Retourne l'ID de session.

Configuration

Nous configurons la session dans la configuration. Si vous écrivez une application qui n'utilise pas de conteneur DI, ces méthodes servent à la configuration. Elles doivent être appelées avant le démarrage de la session.

setName(string $name): static

Définit le nom du cookie dans lequel l'ID de session est transmis. Le nom standard est PHPSESSID. Utile si vous exécutez plusieurs applications différentes sur le même site web.

getName(): string

Retourne le nom du cookie dans lequel l'ID de session est transmis.

setOptions(array $options)static

Configure la session. Il est possible de définir toutes les directives de session PHP (au format camelCase, par ex. au lieu de session.save_path, nous écrivons savePath) ainsi que readAndClose.

setExpiration(?string $time)static

Définit la durée d'inactivité après laquelle la session expire.

setCookieParameters(string $path, ?string $domain=null, ?bool $secure=null, ?string $samesite=null)static

Définition des paramètres pour le cookie. Vous pouvez modifier les valeurs par défaut des paramètres dans la configuration.

setSavePath(string $path)static

Définit le répertoire où sont stockés les fichiers de session.

setHandler(\SessionHandlerInterface $handler)static

Définition d'un gestionnaire personnalisé, voir la documentation PHP.

Sécurité avant tout

Le serveur suppose qu'il communique toujours avec le même utilisateur tant que les requêtes sont accompagnées du même ID de session. La tâche des mécanismes de sécurité est de garantir que ce soit réellement le cas et qu'il ne soit pas possible de voler ou de substituer l'identifiant.

Nette Framework configure donc correctement les directives PHP pour que l'ID de session soit transmis uniquement dans le cookie, le rende inaccessible à JavaScript et ignore les éventuels identifiants dans l'URL. De plus, dans les moments critiques, comme la connexion de l'utilisateur, il génère un nouvel ID de session.

Pour la configuration de PHP, la fonction ini_set est utilisée, que certains hébergeurs interdisent malheureusement. Si c'est le cas de votre hébergeur, essayez de négocier avec lui pour qu'il vous autorise la fonction ou au moins configure le serveur.