veilletech.fr
10 oct. Feed du jour
#05 SYMFONY Article

Symfony 8.2 : des URLs signées à usage unique

Un lien signé sans date de fin, c'est un mot de passe qui traîne dans une boîte mail.

Symfony 8.2 ajoute un argument $version à UriSigner : sa valeur entre dans la signature sans figurer dans l'URL, ce qui permet des liens à usage unique (le hash du mot de passe, par exemple). Signer sans expiration est déprécié et sera refusé en 9.0, et les liens de connexion peuvent désormais signer des paramètres supplémentaires.

2 min de lectureintermédiairevidéo 1:25
Partager
Sommaire5 sections
  1. Ce qui se passe
  2. 1. Un lien à usage unique
  3. 2. L'expiration devient obligatoire
  4. 3. Des paramètres signés dans les liens de connexion
  5. À retenir

Ce qui se passe

Un lien signé (réinitialisation de mot de passe, confirmation d'e-mail, téléchargement) reste valable jusqu'à son expiration, même après usage. Pour l'invalider, il fallait écrire sa propre logique, par exemple un jeton en base. Symfony 8.2 apporte trois changements autour de UriSigner et des liens de connexion.

1. Un lien à usage unique

sign(), check(), checkRequest() et verify() acceptent un nouvel argument $version. Sa valeur est ajoutée à la signature, mais pas à l'URL : le lien n'est valide que tant qu'elle reste identique. Le plus simple est d'y mettre une valeur qui change quand le lien a servi, comme le hash du mot de passe.

PHP
$url = $uriSigner->sign($resetUrl, new \DateInterval('PT1H'), version: $user->getPassword());

// à la réception du lien
$uriSigner->verify($request->getUri(), version: $user->getPassword());

verify() n'invalide rien par lui-même. Le lien meurt quand l'application enregistre le nouveau hash : l'appel suivant lève une UnverifiedSignedUriException. Même principe pour les autres liens : la date de dernière connexion pour un lien de connexion, la date de vérification pour une confirmation d'e-mail.

2. L'expiration devient obligatoire

Une URL signée sans expiration reste valable pour toujours, donc exploitable si elle fuite dans un vieux courriel ou un journal. Appeler UriSigner::sign() sans expiration est déprécié en 8.2 et sera refusé en 9.0. On la passe à chaque appel, ou on fixe une valeur par défaut :

3. Des paramètres signés dans les liens de connexion

Un lien de connexion contient l'identifiant, l'expiration et une signature. Les paramètres ajoutés à la main, comme la page de redirection, n'étaient pas signés : n'importe qui pouvait les modifier. createLoginLink() accepte désormais $parameters, couverts par la signature.

PHP
$lien = $loginLinkHandler->createLoginLink($user, parameters: ['redirect' => '/compte']);

Modifier ou retirer un de ces paramètres invalide le lien. Symfony range les valeurs vérifiées dans l'attribut de requête _login_link_parameters. Dans le handler de succès d'authentification, lisez-les là, jamais dans la query string : les paramètres non signés sont ignorés par Symfony, mais n'importe qui peut les ajouter à l'URL, y compris les clients de messagerie (suivi).

Source : New in Symfony 8.2: Single-Use and Safer Signed URLs, Symfony, 9 octobre 2026. Contributions de Kevin Bond (#64408, #64455) et de Jan Klan (#64271).