Cookies en localhost con dominio explícito

191

Debo estar perdiendo algo básico sobre las cookies. En localhost, cuando configuro una cookie en el lado del servidor y especifico el dominio explícitamente como localhost (o .localhost). la cookie no parece ser aceptada por algunos navegadores.

Firefox 3.5: verifiqué la solicitud HTTP en Firebug. Lo que veo es:

Set-Cookie:
    name=value;
    domain=localhost;
    expires=Thu, 16-Jul-2009 21:25:05 GMT;
    path=/

o (cuando configuro el dominio en .localhost):

Set-Cookie:
    name=value;
    domain=.localhost;
    expires=Thu, 16-Jul-2009 21:25:05 GMT;
    path=/

En cualquier caso, la cookie no se almacena.

IE8: no utilicé ninguna herramienta adicional, pero la cookie no parece estar almacenada también, porque no se devuelve en solicitudes posteriores.

Opera 9.64: tanto localhost como .localhost funcionan , pero cuando verifico la lista de cookies en Preferencias, el dominio se establece en localhost.local a pesar de que aparece en localhost (en el grupo de listas).

Safari 4: tanto localhost como .localhost funcionan , pero siempre se enumeran como .localhost en Preferencias. Por otro lado, una cookie sin un dominio explícito, se muestra como solo localhost (sin punto).

¿Cuál es el problema con localhost? Debido a tal cantidad de inconsistencias, debe haber algunas reglas especiales que involucren localhost. Además, no está completamente claro para mí por qué los dominios deben tener el prefijo de un punto. RFC 2109 declara explícitamente que:

El valor del atributo Dominio no contiene puntos incrustados o no comienza con un punto.

¿Por qué? El documento indica que tiene que hacer algo con seguridad. Tengo que admitir que no he leído toda la especificación (puede que lo haga más tarde), pero suena un poco extraño. En base a esto, sería imposible establecer cookies en localhost.

Jan Zich
fuente
14
Hilo de 6 años y esto sigue siendo un problema. Estoy usando Chrome v40. Ver aquí .
Gaui
55
Chrome 43 ... sigue siendo un error.
Evan Carroll
44
Chrome 54 aquí, NO resuelto
Vahid Amiri
66
Chrome 73 ... aún enfrenta el mismo problema. :(
Code_Crash
2
¿Alguien podría resolver esto? Todavía enfrenta el mismo s *** .. mira esta respuesta SO
Bonjour123 05 de

Respuestas:

236

Por diseño, los nombres de dominio deben tener al menos dos puntos; de lo contrario, el navegador los considerará inválidos. (Ver referencia en http://curl.haxx.se/rfc/cookie_spec.html )

Cuando se trabaja localhost, el dominio de la cookie debe omitirse por completo. Sólo estableciéndolo en ""o NULL, o FALSEen lugar de "localhost", no es suficiente.

Para PHP, vea los comentarios en http://php.net/manual/en/function.setcookie.php#73107 .

Si trabaja con la API de Java Servlet, no llame al cookie.setDomain("...")método en absoluto.

Ralph Buchfelder
fuente
93
No estoy seguro de por qué todos están haciendo +1 en esto, configuré el dominio de la cookie en una cadena nula o falsa o vacía y aún no se guarda si está en localhost.
Justin
55
No veo ningún lugar en RFC6265 sobre los dos puntos en el dominio: tools.ietf.org/html/rfc6265#section-5.2.3 .Net dice configurarlo en ".local" para todos los hosts en su dominio local. Lo que parece consistente con Opera / Safari msdn.microsoft.com/en-us/library/ckch3yd2.aspx
MandoMando
9
@Justin: Hm, probablemente deba omitir por completo el Domain=parámetro al configurar la cookie. Si solo configura el dominio como nulo o vacío, ¿tal vez su marco enviará el Domain=parámetro con ese valor, en lugar de omitirlo? Consulte con, por ejemplo, Firebug.
sleske
2
@Ralph, un millón de gracias, esto me ha mantenido loco por unas horas. Con suerte, configurar el dominio como nulo (estoy en una pila de servidores .Net) funciona de maravilla.
Xose Lluis
44
Esto está algo mal redactado. "Establecer en una cadena nula o falsa o vacía" debería leer "No establecer la parte 'dominio' de la cookie en absoluto". Por ejemplo, el uso de una prueba simple para omitir por completo la sección de dominio de la cookie funciona para localhost:((domain && domain !== "localhost") ? ";domain="+domain : "")
L0j1k
34

Estoy ampliamente de acuerdo con @Ralph Buchfelder, pero aquí hay algo de amplificación de esto, al experimentar al intentar replicar un sistema con varios subdominios (como example.com, fr.example.com, de.example.com) en mi máquina local ( OS X / Apache / Chrome | Firefox).

Edité / etc / hosts para señalar algunos subdominios imaginarios en 127.0.0.1:

127.0.0.1 localexample.com
127.0.0.1 fr.localexample.com
127.0.0.1 de.localexample.com

Si estoy trabajando en fr.localexample.com y dejo fuera el parámetro de dominio, la cookie se almacena correctamente para fr.localexample.com, pero no es visible en los otros subdominios.

Si uso un dominio de ".localexample.com", la cookie se almacena correctamente para fr.localexample.com y es visible en otros subdominios.

Si uso un dominio de "localexample.com", o cuando estaba probando un dominio de solo "localexample" o "localhost", la cookie no se almacenaba.

Si uso un dominio de "fr.localexample.com" o ".fr.localexample.com", la cookie se almacena correctamente para fr.localexample.com y es (correctamente) invisible en otros subdominios.

Por lo tanto, el requisito de que necesite al menos dos puntos en el dominio parece ser correcto, aunque no entiendo por qué debería serlo.

Si alguien quiere probar esto, aquí hay un código útil:

<html>
<head>
<title>
Testing cookies
</title>
</head>
<body>
<?php
header('HTTP/1.0 200');
$domain = 'fr.localexample.com';    // Change this to the domain you want to test.
if (!empty($_GET['v'])) {
    $val = $_GET['v'];
    print "Setting cookie to $val<br/>";
    setcookie("mycookie", $val, time() + 48 * 3600, '/', $domain);
}
print "<pre>";
print "Cookie:<br/>";
var_dump($_COOKIE);
print "Server:<br/>";
var_dump($_SERVER);
print "</pre>";
?>
</body>
</html>
xgretsch
fuente
30

localhost: puede usar: domain: ".app.localhost"y funcionará. El parámetro 'dominio' necesita 1 o más puntos en el nombre de dominio para configurar las cookies. A continuación, puede tener sesiones de trabajo a través de los subdominios localhost tales como: api.app.localhost:3000.

AmpT
fuente
1
También probado y trabajando en un servidor node.js, usando Express 3.x, enexpress.session({cookie: { domain: '.app.localhost', maxAge: 24 * 60 * 60 * 1000 }})
AmpT
3
¡ESTO debe seleccionarse como respuesta si está utilizando dominios locales! Poner un punto antes del subdominio soluciona mi problema.
Foxhoundn
1
Entonces, ¿de dónde .app.viene este antecedente de la venida? ¿Es parte de algunas especificaciones? ¿Y es aplicable para todos los dominios no conformes (aquellos sin dos puntos)? Además, ¿funcionará con navegadores antiguos? : ^)
user2173353
Oh ... ahora entiendo ... Es solo un truco engañar a los navegadores. OKAY.
user2173353
14

Cuando se configura una cookie con un dominio explícito de 'localhost' de la siguiente manera ...

Set-Cookie: nombre = valor; dominio = localhost ; caduca = jue, 16-jul-2009 21:25:05 GMT; ruta = /

... luego los navegadores lo ignoran porque no incluye al menos dos períodos y no es uno de los siete dominios de nivel superior manejados especialmente .

... los dominios deben tener al menos dos (2) o tres (3) períodos en ellos para evitar dominios de la forma: ".com", ".edu" y "va.us". Cualquier dominio que falle dentro de uno de los siete dominios especiales de nivel superior enumerados a continuación solo requiere dos períodos. Cualquier otro dominio requiere al menos tres. Los siete dominios especiales de nivel superior son: "COM", "EDU", "NET", "ORG", "GOV", "MIL" e "INT".

Tenga en cuenta que el número de períodos anteriores probablemente supone que se requiere un período inicial. Sin embargo, este período se ignora en los navegadores modernos y probablemente debería leer ...

al menos uno (1) o dos (2) períodos

Tenga en cuenta que el valor predeterminado para el atributo de dominio es el nombre de host del servidor que generó la respuesta de cookie .

Por lo tanto, una solución alternativa para las cookies que no se configuran para localhost es simplemente no especificar un atributo de dominio y dejar que el navegador use el valor predeterminado; esto no parece tener las mismas restricciones que un valor explícito en el atributo de dominio.

Scott Munro
fuente
No hice DV, pero supongo que la razón por la que otros lo hicieron es porque su respuesta realmente no agrega mucho valor. El requisito de dos períodos y dejar en blanco el atributo de dominio se han discutido en otras respuestas. Además, las cosas que agregó sobre un dominio de nivel superior parecen ser incorrectas. En mi experiencia eso no es un requisito.
TTT
@TTT ¿No está seguro si llegó al bit en mi respuesta donde digo que debería ser al menos 1 o dos períodos dependiendo del TLD porque se ignoran los períodos iniciales? Así que proporcioné algunos antecedentes sobre el problema y agregué un punto que no creo que esté cubierto en otra parte: las reglas son diferentes para un dominio explícito y el que el navegador usa de manera predeterminada. Parece que me agrega algo de valor.
Scott Munro
1
Dejar el dominio nulo (sin configurarlo en absoluto) NO hace que Chrome conserve la cookie para localhost. Todavía lo ignora. Tenga en cuenta que esto solo se aplica a las cookies "permanentes" (las que establecen una fecha de vencimiento), ya que se guardará en las cookies de "sesión" para localhost (las que no establecen una fecha de vencimiento).
Triynko el
3

Resultados que había variado por navegador.

Chrome- 127.0.0.1 funcionó pero localhost .localhost y "" no. Firefox- .localhost funcionó pero localhost, 127.0.0.1 y "" no.

No he probado en Opera, IE o Safari


fuente
3
Acabo de probarlo con Chrome V.22.0.1229.94 m: configurar una cookie para localhost sin dar un Domain=parámetro funciona. Domain=También funciona, pero Domain=localhostno funciona.
sleske
3

Pasé mucho tiempo resolviendo este problema yo mismo.

Usar PHP y Nothing en esta página me funcionó. Finalmente me di cuenta en mi código que el parámetro 'seguro' para el session_set_cookie_params () de PHP siempre se estaba configurando como VERDADERO.

Como no estaba visitando localhost con https, mi navegador nunca aceptaría la cookie. Entonces, modifiqué esa parte de mi código para establecer condicionalmente el parámetro 'seguro' basado en que $ _SERVER ['HTTP_HOST'] sea 'localhost' o no. Trabajando bien ahora.

Espero que esto ayude a alguien.

James Jacobson
fuente
2

Si está configurando una cookie de otro dominio (es decir, configura la cookie al hacer una solicitud de origen cruzado XHR), entonces debe asegurarse de establecer el withCredentialsatributo en verdadero en la solicitud XMLHttpRequest que utiliza para recuperar la cookie como se describe aquí

Aidan Ewen
fuente
Sí, incluso con eso. Todavía no funciona con solicitudes de dominio cruzado. Navegador - Safari, IE 11
Rohit Kumar
2

puede utilizar localhost.orgo, mejor .localhost.orgdicho, siempre resolverá127.0.0.1

qoomon
fuente
1

Tuve mucha mejor suerte probando localmente usando 127.0.0.1 como dominio. No estoy seguro de por qué, pero tuve resultados mixtos con localhost y .localhost, etc.

Toby
fuente
1

Ninguna de las soluciones sugeridas funcionó para mí: establecerla como nula, falsa, agregar dos puntos, etc., no funcionó.

Al final, acabo de eliminar el dominio de la cookie si es localhost y eso ahora funciona para mí en Chrome 38 .

Código anterior (no funcionó):

document.cookie = encodeURI(key) + '=' + encodeURI(value) + ';domain=.' + document.domain + ';path=/;';

Nuevo código (ahora funcionando):

 if(document.domain === 'localhost') {
        document.cookie = encodeURI(key) + '=' + encodeURI(value) + ';path=/;' ;
    } else {
        document.cookie = encodeURI(key) + '=' + encodeURI(value) + ';domain=.' + document.domain + ';path=/;';
    }
DJ_Polly
fuente
1

Tuve el mismo problema y lo solucioné poniendo 2 puntos en el nombre de la cookie sin especificar ningún dominio.

set-cookie: name.s1.s2=value; path=/; expires=Sun, 12 Aug 2018 14:28:43 GMT; HttpOnly
Eric B.
fuente
1

Parece que hay un problema cuando lo usas https://<local-domain>y luego http://<local-domain>. El http://sitio no envía cookies con solicitudes después de que el https://sitio las configura. Forzar recarga y borrar caché no ayuda. Solo funciona la eliminación manual de cookies. Además, si los borro en la https://página, la http://página comienza a funcionar nuevamente.

Parece estar relacionado con "Cookies seguras estrictas". Buena explicación aquí . Fue lanzado en Chrome 58 el 19/04/2017.

Parece que Chrome de hecho registra cookies seguras y no seguras, ya que mostrará las cookies correctas según el protocolo de la página al hacer clic en el icono de la barra de direcciones.

Pero Developer tools > Application > Cookiesno mostrará una cookie no segura cuando haya una cookie segura con el mismo nombre para el mismo dominio, ni enviará la cookie no segura con ninguna solicitud. Esto parece un error de Chrome, o si se espera este comportamiento, debería haber alguna forma de ver las cookies seguras en una httppágina y una indicación de que se están anulando.

La solución consiste en utilizar diferentes cookies con nombre dependiendo de si son para un sitio http o https, y nombrarlas específicamente para su aplicación. Un __Secure-prefijo indica que la cookie debe ser estrictamente segura, y también es una buena práctica porque seguro y no seguro no colisionará. También hay otros beneficios para los prefijos.

El uso de diferentes /etc/hostsdominios para https frente a acceso http también funcionaría, pero una https://localhostvisita accidental evitará que las cookies del mismo nombre funcionen en los http://localhostsitios, por lo que esta no es una buena solución.

He presentado un informe de error de Chrome .

vaughan
fuente
0

document.cookie = valuename + "=" + value + ";" + caduca + "; dominio =; ruta = /";

este "dominio =; ruta = /"; tomará un dominio dinámico ya que su cookie funcionará en el subdominio. si quieres probar en localhost funcionará

Abhishek SInha
fuente
0

Ninguna de las respuestas aquí funcionó para mí. Lo arreglé colocando mi PHP como lo primero en la página.

Al igual que otros encabezados, las cookies deben enviarse antes de cualquier salida de su script (esta es una restricción de protocolo). Esto requiere que realice llamadas a esta función antes de cualquier salida, incluidas las etiquetas y cualquier espacio en blanco.

De http://php.net/manual/en/function.setcookie.php

john ktejik
fuente
sin embargo, eso no tiene nada que ver con el problema, eso simplemente no es cometer el error de enviar cualquier otra salida antes de los encabezados
Marnes
0

Estaba jugando un poco.

Set-Cookie: _xsrf=2|f1313120|17df429d33515874d3e571d1c5ee2677|1485812120; Domain=localhost; Path=/

funciona en Firefox y Chrome a partir de hoy. Sin embargo, no encontré una manera de hacerlo funcionar con curl. Intenté Host-Header y --resolver, sin suerte, cualquier ayuda apreciada.

Sin embargo, funciona en curl, si lo configuro en

Set-Cookie: _xsrf=2|f1313120|17df429d33515874d3e571d1c5ee2677|1485812120; Domain=127.0.0.1; Path=/

en lugar. (Que no funciona con Firefox).

Micha
fuente
0

Otro detalle importante, expires = debe usar el siguiente formato de fecha y hora: Wdy, DD-Mon-AAAA HH: MM: SS GMT ( RFC6265 - Sección 4.1.1 ).

Set-Cookie:
  name=value;
  domain=localhost;
  expires=Thu, 16-07-2019 21:25:05 GMT;
  path=/
Tralamazza
fuente
55
-1 La especificación actual para cookies es RFC 6265, tools.ietf.org/html/rfc6265 , que establece explícitamente que se permiten años de 4 dígitos. Por lo tanto, es una mala idea usar años de 2 dígitos, que diferentes navegadores interpretarán de manera diferente.
sleske
Correcto. Ref RFC6265 sección 4.1.1
Zen Cart
44
Correcto, pero en junio de 2011 no encontré este RFC. Entonces, aunque esta información ahora es incorrecta, cuando escribí no lo era.
Tralamazza
44
No lo tome como un desaire, las cosas cambian y todos debemos ayudar a garantizar que las respuestas se mantengan actualizadas. Simplemente actualice su respuesta con la información más reciente que @sleske le haya brindado y agradézcale su ayuda.
Matthew Purdon el
0

Después de mucha experimentación y lectura de varias publicaciones, esto funcionó. Podría configurar varias cookies, volver a leerlas y configurar el tiempo negativo y eliminarlas.

func addCookie(w http.ResponseWriter, name string, value string) {
    expire := time.Now().AddDate(0, 0, 1)
    cookie := http.Cookie{
       Name:    name,
       Value:   value,
       Expires: expire,
       Domain:  ".localhost",
       Path:    "/",
    }
    http.SetCookie(w, &cookie)
}
Saied
fuente
0

Lo único que funcionó para mí fue establecer Path=/ la cookie.

Además, el valor predeterminado de un atributo de ruta parece ser diferente de los navegadores a los navegadores, aunque probé solo dos de ellos (Firefox y Chrome).

Chrome intenta establecer una cookie tal como está; Si el pathatributo se omite en el Set-Cookieencabezado, no se almacenará ni se ignorará.

Sin embargo, Firefox almacena una cookie incluso sin un pathatributo explícito . Simplemente lo configuró con la ruta solicitada; mi URL de solicitud era /api/v1/usersy la ruta se configuró /api/v1automáticamente.

De todos modos, ambos navegadores funcionaron cuando pathse configuró /incluso sin un dominio explícito, es decir, Domain=localhosto algo así. Por lo tanto, hay algunas diferencias en la forma en que cada navegador maneja las cookies.

이준형
fuente