51 votes

Cookies avec et sans le domaine spécifié (incohérence du navigateur)

J'ai remarqué que y a des incohérences entre les navigateurs en matière de cookies.

Cela va être assez long donc nu avec moi.

Note: j'ai configuré un domaine dans mon fichier host, appelé "testdomain.com", ce bug ne fonctionnent pas lors de l'utilisation de "localhost".

Note2: je suis curieuse de savoir comment cela fonctionne sur un serveur Apache/PHP si lorsque vous récupérez un cookie de nom si elle donne une collection de cookies.

Wikipédia

Wikipedia précise que: http://en.wikipedia.org/wiki/HTTP_cookie#Domain_and_Path

Domaine et le Chemin d'accès
Le cookie de domaine et le chemin de définir le champ d'application de la cookie-ils dire au navigateur que les cookies ne doit être renvoyé à le serveur pour le domaine et le chemin d'accès. Si non spécifié, ils par défaut le domaine et le chemin d'accès de l'objet qui a été demandé.

Donc, si nous pousser vers le bas:

Response.Cookies.Add(new HttpCookie("Banana", "2")
{

});

Nous devrions obtenir un cookie avec le domaine utilisé étant le domaine de l'objet demandé, dans ce cas, il doit être "testdomain.com".

W3

W3 états dans le cahier des charges pour les cookies: http://www.w3.org/Protocols/rfc2109/rfc2109

Domaine=domaine

Facultatif. Le Domaine de l'attribut spécifie le domaine pour lequel le cookie est valide. Explicitement précisé domaine doit toujours commencer avec un point.

Donc, si nous pousser vers le bas:

Response.Cookies.Add(new HttpCookie("Banana", "1")
{
    Domain = Request.Url.Host
});

Nous avons poussé le nom d'hôte explicitement, nous devrions obtenir un nom de domaine sur le cookie qui serait précédé d'un point, dans ce cas, il doit être ".testdomain.com".

Il stipule également ce qui est sur Wikipédia:

Domaine par Défaut à la demande de l'hôte. (À noter qu'il n'y a pas de point à le début de la demande de l'hôte.)


Avec moi jusqu'à présent?

Si j'utilise la première méthode, la définition d'un Domaine:

Response.Cookies.Add(new HttpCookie("Banana", "1")
{
    Domain = Request.Url.Host
});

Ce sont les résultats:

IE9: 1 cookie

IE with 1 cookie and domain explicitly set

Opéra: 1 cookie

Opera with 1 cookie and domain explicitly set

Firefox: 1 cookie

Firefox with 1 cookie and domain explicitly set

Google Chrome: 1 cookie

Chrome with 1 cookie and domain explicitly set

Comme vous pouvez le voir, les deux Opera et IE définie à la fois EXPLICITE de domaine sans point de préfixe.

Firefox et Chrome NE définir le domaine EXPLICITE avec un point de préfixe.

Si j'utilise le code suivant:

Response.Cookies.Add(new HttpCookie("Banana", "2")
{

});

IE / Opera: les Deux ont exactement le même résultat, le domaine SANS point de préfixe.

Curieusement, Firefox et Chrome à la fois créer des cookies SANS le point de préfixe.

(J'ai effacé tous les cookies, et a couru de nouveau le code)

Firefox:

Firefox with 1 cookie and domain explicitly set

Chrome:

Chrome with 1 cookie and domain explicitly set

MORCEAU INTÉRESSANT

C'est là que ça devient intéressant. Si j'écris les cookies, l'un après l'autre, comme ceci:

Response.Cookies.Add(new HttpCookie("Banana", "1")
{
    Domain = Request.Url.Host
});
Response.Cookies.Add(new HttpCookie("Banana", "2")
{

});

PERSONNELLEMENT, je m'attends à un témoin pour exister dans le navigateur, car je suppose que c'est basé sur le nom du cookie.

Voici ce que j'ai observé:

Dans IE / Opera, le DERNIER cookie est le cookie qui est utilisé. C'est parce que le nom du Cookie et nom de Domaine sont identiques.

Si vous définissez explicitement un nom de domaine avec un point, les deux navigateur va encore voir 1 cookie, le dernier témoin du même nom.

Chrome et Firefox sur l'autre main, voir plus que 1 cookie:

J'ai écrit le code JavaScript suivant pour vider les valeurs de la page:

<script type="text/javascript">

(function () {
    var cookies = document.cookie.split(';');
    var output = "";

    for (var i = 0; i < cookies.length; i++) {
        output += "<li>Name " + cookies[i].split('=')[0];
        output += " - Value " + cookies[i].split('=')[1] + "</li>";
    }

    document.write("<ul>" + output + "</ul>");
})();

</script>

Ce sont les résultats:

IE - 2 cookies (navigateur voit 1):

IE - 2 cookies set, the outcome

Opéra - 2 cookies (navigateur voit 1):

enter image description here

Firefox - 2 cookies et le navigateur voit 2!:

enter image description here

Chrome - 2 cookies et le navigateur voit 2!:

enter image description here


Maintenant, vous vous demandez probablement wtf tout cela est.

Bien:

  1. Lorsque vous accédez au cookie par Nom en C#, il vous donne 1 cookie. (le premier témoin qui a ce nom)
  2. Le navigateur envoie TOUS les cookies du serveur
  3. Le navigateur n'envoie pas d'autres informations que la clé/valeur du cookie. (cela signifie que le serveur ne se soucie pas du domaine)
  4. Vous pouvez accéder à la fois les témoins du même nom, si vous les récupérer par index

Le problème...

Nous avons dû changer notre Authentification de préciser le domaine dans le cookie lorsque nous avons poussé vers le bas.

C'est Chrome et Firefox, les utilisateurs ne sont plus capables de connexion, parce que le serveur serait tenter d'authentifier l'ancien auth cookie. C'est parce que (à partir de ma compréhension), il utilise le Cookie d'Authentification Nom de récupérer le cookie.

Même quand il y a deux témoins, le premier est extrait qui se trouve être l'ancien, l'authentification échoue, l'utilisateur n'est pas connecté. PARFOIS, le bon cookie est en premier dans la liste, et le succès de l'authentification...

Au départ nous avons résolu ce problème en poussant un cookie avec l'ancien domaine à échéance il. Cela a fonctionné dans Chrome et Firefox.

Mais elle a cassé IE/Opera depuis deux navigateurs n'avez pas de soins sur le domaine et qu'à comparer les cookies en fonction du nom.

Ma conclusion est que le nom de domaine sur un cookie est un totale perte de temps.

En supposant que nous devons spécifier le domaine, et nous ne pouvons pas compter sur les utilisateurs pour effacer le cache du navigateur. Comment pouvons-nous résoudre ce problème?

Mise à jour:

Creuser dans comment .NET signes d'un utilisateur.

if (FormsAuthentication._CookieDomain != null)
{
    httpCookie.Domain = FormsAuthentication._CookieDomain;
}

On dirait qu'il est tout à fait possible pour l'authentification de Formulaires pour pousser l'expiration d'un Auth cookie, qui est totalement sans rapport avec le cookie de l'utilisateur est authentifié avec. Il n'utilise pas le courant Auth domaine de validité du Cookie.

Qui il ne peut pas utiliser de toute façon, étant donné que le domaine n'est pas poussé vers le serveur avec le cookie.

Mise à jour 2

Il semble FormsAuthentication est vraiment cassé. Si vous utiliser explicitement un nom de domaine sur un cookie lorsque vous authentifier l'utilisateur, d'attendre la session de délai d'attente, puis actualisez la page, la méthode de génération de le cookie utilisé par FormsAuthentication résultats dans le domaine null, qui provoque le navigateur pour attribuer un nom de domaine sans point.

Il exige que les Formulaires d'être assigné à un domaine à l'avant pour qu'elle soit affectée à l'cookie, cela casse un multi-locataire système...

10voto

Phill Points 7558

@WilliamBZA suggestion du permis de résoudre le problème initial, mais alors signout/délai d'expiration de session bug que les résultats dans le cookie de la création d'un implicite de domaine du cookie m'a fait venir à la conclusion que la solution est...

Ne pas utiliser des cookies dans .NET jamais...

Il y a beaucoup trop de problèmes, assurez-vous qu'ils peuvent être résolus par être plus explicite sur la Forme/Domaine, Cookie de Domaine, etc. Pour s'assurer que le bon nom de domaine est utilisé partout. Mais si votre application héberge plusieurs domaines ou est multi-locataire, puis ça devient trop problématique.

La leçon est apprise. Ne pas utiliser des cookies.

5voto

WilliamBZA Points 96

Vous ne pouvez pas comprendre pourquoi les cookies sont traités différemment, mais une solution rapide consisterait à utiliser un nom de cookie différent pour chaque application plutôt que d'utiliser le domaine du cookie.

Dans le cas de l'authentification par formulaire, changez le nom du cookie ASPXAUTH.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X