web-dev-qa-db-fra.com

Façon correcte de supprimer les cookies côté serveur

Pour mon processus d'authentification, je crée un jeton unique lorsqu'un utilisateur se connecte et l'insère dans un cookie utilisé pour l'authentification.

Donc, je voudrais envoyer quelque chose comme ça depuis le serveur:

Set-Cookie: token=$2a$12$T94df7ArHkpkX7RGYndcq.fKU.oRlkVLOkCBNrMilaSWnTcWtCfJC; path=/;

Ce qui fonctionne sur tous les navigateurs. Ensuite, pour supprimer un cookie, j'envoie un cookie similaire avec le champ expires défini pour le 1er janvier 1970.

Set-Cookie: token=$2a$12$T94df7ArHkpkX7RGYndcq.fKU.oRlkVLOkCBNrMilaSWnTcWtCfJC; path=/; expires=Thu, Jan 01 1970 00:00:00 UTC; 

Et cela fonctionne bien sur Firefox mais ne supprime pas le cookie sur IE ou Safari.

Alors, quel est le meilleur moyen de supprimer un cookie (sans JavaScript, de préférence)? La méthode set-the-expires-in-the-past semble volumineuse. Et aussi pourquoi cela fonctionne-t-il dans FF mais pas dans IE ou Safari?)

115
Joshkunz

Envoi de la même valeur de cookie avec ; expires annexé ne détruira pas le cookie.

Invalider le cookie en définissant une valeur vide et inclure également un champ expires:

Set-Cookie: token=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT

Notez que vous ne pouvez pas forcer tous les navigateurs à supprimer un cookie. Le client peut configurer le navigateur de manière à ce que le cookie persiste, même s'il a expiré. Définir la valeur comme décrit ci-dessus résoudrait ce problème.

189
Lekensteyn

Définir "expire" sur une date passée est le moyen standard de supprimer un cookie.

Votre problème vient probablement du fait que le format de la date n’est pas conventionnel. IE attend probablement uniquement l'heure GMT.

12
irreputable

Au moment de la rédaction de cette réponse, le réponse acceptée à cette question semble indiquer que les navigateurs ne sont pas obligés de supprimer un cookie lors de la réception d'un cookie de remplacement dont la valeur Expires est dans le champ. passé. Cette affirmation est fausse. Définir Expires comme étant dans le passé est le moyen standard et conforme aux spécifications de supprimer un cookie, et les agents utilisateurs sont tenus de le respecter.

L'utilisation d'un attribut Expires dans le passé pour supprimer un cookie est correcte et permet de supprimer les cookies dictés par la spécification. La section exemples de RFC 6255 indique:

Enfin, pour supprimer un cookie, le serveur renvoie un en-tête Set-Cookie avec une date d'expiration antérieure. Le serveur réussira à supprimer le cookie uniquement si les attributs Path et Domain de l'en-tête Set-Cookie correspondent aux valeurs utilisées lors de la création du cookie.

La section Configuration requise pour l'agent utilisateur inclut les conditions suivantes, qui ont pour effet qu'un cookie doit être immédiatement supprimé, si l'agent utilisateur reçoit un nouveau cookie avec même nom dont la date d'expiration est passée

  1. Si [lors de la réception d'un nouveau cookie], le magasin de cookies contient un cookie portant le même nom, le même domaine et le même chemin que le cookie nouvellement créé:

    1. ...
    2. ...
    3. Mettez à jour l'heure de création du cookie nouvellement créé pour qu'elle corresponde à l'heure de création de l'ancien cookie.
    4. Retirez le vieux cookie du magasin de cookies.
  2. Insérez le cookie nouvellement créé dans le magasin de cookies.

Un cookie est "expiré" s'il a déjà une date d'expiration.

L'agent utilisateur DOIT expulser tous les cookies expirés du magasin de cookies si, à tout moment, un cookie expiré existe dans le magasin de cookies.

Les points 11-3, 11-4 et 12 ci-dessus ensemble signifient que lorsqu'un nouveau cookie reçoit le même nom, le même domaine et le même chemin, l'ancien cookie doit être supprimé et remplacé par le nouveau. Enfin, le point ci-dessous relatif aux cookies expirés indique en outre qu'après cela, le cookie nouveau doit aussi être immédiatement expulsé. La spécification n'offre aucune marge de manœuvre aux navigateurs sur ce point; si un navigateur offrait à l'utilisateur la possibilité de désactiver l'expiration du cookie, comme le suggère la réponse acceptée par certains navigateurs, il serait alors contraire aux spécifications. (Une telle fonctionnalité aurait également peu d’utilité et, autant que je sache, elle n’existe dans aucun navigateur.)

Pourquoi, alors, le PO de cette question a-t-il observé l'échec de cette approche? Bien que je n’ai pas nettoyé une copie d’Internet Explorer pour vérifier son comportement, j’imagine que c’est parce que la valeur Expires de l’OP était mal formée! Ils ont utilisé cette valeur:

expires=Thu, Jan 01 1970 00:00:00 UTC;

Cependant, ceci est syntaxiquement invalide de deux manières.

Le section syntaxe de la spécification indique que la valeur de l'attribut Expires doit être un

rfc112 - date, définie dans [RFC2616], paragraphe 3.3.1

Après le deuxième lien ci-dessus, nous trouvons ceci donné à titre d'exemple du format:

Sun, 06 Nov 1994 08:49:37 GMT

et trouver que la définition de la syntaxe ...

  1. exige que les dates soient écrites au format jour mois année, et non pas mois jour année tel qu'utilisé par le demandeur de la question.

    Plus précisément, il définit rfc1123-date comme suit:

    rfc1123-date = wkday "," SP date1 SP time SP "GMT"
    

    et définit date1 comme ça:

    date1        = 2DIGIT SP month SP 4DIGIT
                 ; day month year (e.g., 02 Jun 1982)
    

et

  1. n'autorise pas UTC comme fuseau horaire.

    La spécification contient la déclaration suivante sur les décalages de fuseau horaire acceptables dans ce format:

    Tous les horodatages HTTP DOIVENT être représentés en heure GMT (Greenwich Mean Time), sans exception.

    De plus, si nous approfondissons la spécification originale de ce format datetime, nous constatons que, dans sa spécification initiale, dans https://tools.ietf.org/html/rfc822 , le Syntax section liste "UT" (signifiant "temps universel") comme valeur possible, mais pas ne liste pas UTC (temps universel coordonné) comme valide. Autant que je sache, l'utilisation de "UTC" dans ce format de date a jamais été valide; ce n'était pas une valeur valide lorsque le format a été spécifié pour la première fois en 1982, et la spécification HTTP a adopté une version strictement plus du format en interdisant l'utilisation de toutes les valeurs de "zone" autres que "GMT".

Si le demandeur de la question ici avait plutôt utilisé un attribut Expires comme ceci, alors:

expires=Thu, 01 Jan 1970 00:00:00 GMT;

alors cela aurait vraisemblablement fonctionné.

10
Mark Amery