web-dev-qa-db-fra.com

Cookie de session en cours de suppression lors du déplacement sous SSL

La version courte:

Un cookie de session est défini sur un site de développement, mais il n'est pas récupéré lorsque je passe à SSL (le panier se vide lorsque vous passez à la caisse).

Lorsqu'il est défini sur le site www:

# http://dev.domain.ext
Name    devSID
Value   2e9f1b1f6ca718d0961d0257f3297c1a
Host    .domain.ext
Path    /
Secure  No
Expires At End Of Session

Et du côté ssl:

# https://dev.domain.ext
Name    devSID
Value   6fe74ccc91b67bce46165d005bfd157e
Host    .domain.ext
Path    /
Secure  No
Expires At End Of Session

Il semble que le cookie de session créé sous www ne soit pas récupéré sous le côté ssl (à l'inverse, il ne va pas dans l'autre sens non plus, s'il est créé le Le côté ssl n'est pas capté du côté www).

Quelqu'un a des idées brillantes?


La version longue (moi le travaillant)

J'ai un site de développement actuellement sur un sous-domaine dev; le cookie de session en cours de définition est accessible sur tout le domaine en utilisant un format de type . domain.ext et est créé à l'aide d'un objet PHP qui charge les paramètres à partir d'une table de configuration de la base de données .

Le même objet crée le cookie dans tous les sous-domaines, il ne crée donc pas de cookies en double avec des valeurs de chemin d'accès différentes.

Name    devSID
Value   [alpha-numeric hash value]
Host    .domain.ext
Path    /
Secure  No
Expires At End Of Session

Sur mon ordinateur local, les sous-domaines utilisés sont www et ssl. La chaîne de l'hôte se lit ainsi . Dev.local et le cookie est lu avec joie. sur tout le domaine (à l'aide du https-vhosts.conf d'Apache pour configurer les domaines sur le serveur et du fichier des hôtes Windows pour les pointer vers 127.0.0.1) ... et tout est parfait.

Cependant, lorsque je le télécharge sur un serveur de développement en ligne (avec ses propres paramètres de configuration et de vhosts), le cookie est supprimé lors du déplacement des côtés www à ssl du site et Je ne vois aucune raison logique à cela.

C'est ce qui se passe dans vhosts:

<VirtualHost [IP ADDRESS]:80 >
    ServerName www.dev.domain.ext
    ServerAlias www.dev.domain.ext dev.domain.ext

    ...
</VirtualHost>

<VirtualHost [IP ADDRESS]:443 >
    [SSL ENGINE BIT]

    ServerName ssl.dev.domain.ext
    ServerAlias ssl.dev.domain.ext dev.domain.ext

    ...
</VirtualHost>

Techniquement, les sous-domaines (tels que définis par NomServeur) sont www.dev et ssl.dev mais aucun d’entre eux n’a été enregistré sur un serveur DNS - les serveurs DNS ne disposent que le plus haut domaine dev enregistré; j'ai donc ajouté cela à la liste ServerAlias ​​et des entrées ont été entrées dans mon fichier d'hôtes Windows afin que les sous-domaines non enregistrés soient résolus sur ma machine.

[IP ADDRESS]    www.dev.domain.ext
[IP ADDRESS]    ssl.dev.domain.ext

Et les paramètres de cookie de session:

Name    devSID
Value   [alpha-numeric hash value]
Host    .domain.ext
Path    /
Secure  No
Expires At End Of Session

Donc théoriquement, le cookie devrait être accessible à travers tous sous-domaines (même le site actif en fait puisque je ne l'ai pas limité au sous-domaine dev) mais chaque fois que je passe du côté SSL, le cookie est supprimé.

4
CD001

OK - Je pense que je viens de le résoudre, merci à Dave et Emil; alors que vous n'avez pas enfoncé le clou - vous l'avez fait m'a fait regarder au bon endroit (et m'a rappelé Fiddler pour le débogage) .

Théoriquement, ce que je faisais ne devrait pas avoir cassé le cookie, mais ce l'était, mais seulement de temps en temps (par exemple, l'accès au serveur de dev en ligne a bien fonctionné, mais pas au bureau). ..

Fondamentalement, le contrôle des cookies de session de PHP session_set_cookie_params() ne gère pas les dates d'expiration non nulles comme je le souhaiterais; Si vous configurez la session pour qu'elle expire dans 15 minutes, time() + 900 elle expirera dans 15 minutes à partir du moment où le cookie est défini - il ne mettra pas à jour l'heure d'expiration. Donc, ce que je faisais, à l'intérieur du constructeur privé de mon objet Session (c'est un Singleton), était:

if($this->cookie_lifetime != 0) {
      if(is_null($bUseHTTPCookie)) { setcookie($this->getName(), $this->getID(), (time() + $this->cookie_lifetime), $this->cookie_path, $this->cookie_domain, $this->use_ssl_cookie_only); }
      else { setcookie($this->getName(), $this->getID(), (time() + $this->cookie_lifetime), $this->cookie_path, $this->cookie_domain, $this->use_ssl_cookie_only, $this->use_http_cookie_only); }
}

Qui est censé mettre à jour le cookie de session pour prolonger le temps de 15 minutes chaque fois que la page est actualisée; et cela fonctionnait bien localement et accédait au serveur de dev depuis chez vous mais ne fonctionnait pas à partir de ma machine au travail (cela pourrait fonctionner une fois dans environ 50) .

Je soupçonne que c'est un problème de latence; que le temps nécessaire à session_set_cookie_params() pour écrire le cookie sur ma machine grinçante dans mon bureau grinçante ait peut-être été suffisamment long pour que le script atteigne la setcookie() censée mettre à jour ce cookie ... et de mauvaises choses sont arrivées.

J'ai remarqué, dans Fiddler, que lorsqu'une page prenait beaucoup de temps pour charger le cookie de session n'était pas défini, ce qui implique que setcookie() était en cours d'exécution avant l'identifiant de session. était en place et définissait donc une chaîne vide comme valeur du cookie ... ce qui, bien sûr, supprimera le cookie.

Maintenant, j'ai commenté la fonction setcookie() qui semble fonctionner depuis le bureau!

Oui, pas besoin de me dire, je suis un idiot - merci :)

3
CD001

Je suppose que cela a quelque chose à voir avec le domaine des cookies. Essayez de créer un script avec un appel à la fonction phpinfo () et examinez la valeur de la valeur session.cookie_domain sur les vhosts www et ssl?

0
Emil Rasmussen

Vous regardez sous la mauvaise hypothèse. Lors du passage de http à https, il est traité comme un nouveau domaine, un nouveau serveur, un tout nouveau, de sorte que les cookies ne peuvent pas être conservés entre les connexions ssl et non ssl, bien qu'ils se trouvent sur le même serveur, le même domaine.

Une solution à ce changement consiste à utiliser une redirection de chaîne de requête. Par exemple:

Vous êtes sur http: /www.domain.tld et disposez d'un cookie de session associé à la session PHPSESSID = 123

Dans les liens permettant de changer de serveur, vous devez ajouter une chaîne de requête du type https: //secure.domain.tld/? Key = 876 - supposons qu'il s'agit d'un md5 hash de la valeur de cookie.

Lorsque l'utilisateur clique et atteint la connexion https, vous devriez être en mesure d'identifier cette chaîne de requête et de charger la session qu'il utilisait avec une navigation autre que ssl.

Cela devrait résoudre votre problème.

0
Dave