Cookies no host local com domínio explícito

191

Devo estar sentindo falta de algo básico sobre cookies. No localhost, quando defino um cookie no servidor e especifique o domínio explicitamente como localhost (ou .localhost). o cookie não parece ser aceito por alguns navegadores.

Firefox 3.5: verifiquei a solicitação HTTP no Firebug. O que eu vejo é:

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

ou (quando defino o domínio como .localhost):

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

Nos dois casos, o cookie não é armazenado.

IE8: Eu não usei nenhuma ferramenta extra, mas o cookie não parece ser armazenado também, porque não está sendo enviado de volta em solicitações subsequentes.

Opera 9.64: Localhost e .localhost funcionam , mas quando eu checo a lista de cookies nas Preferências, o domínio é definido como localhost.local, mesmo listado em localhost (no agrupamento de listas).

Safari 4: localhost e .localhost funcionam , mas sempre são listados como .localhost nas Preferências. Por outro lado, um cookie sem um domínio explícito, sendo mostrado apenas como localhost (sem ponto).

Qual é o problema com o localhost? Devido a esse número de inconsistências, deve haver algumas regras especiais envolvendo o host local. Além disso, não está completamente claro para mim por que os domínios devem ser prefixados por um ponto? A RFC 2109 afirma explicitamente que:

O valor para o atributo Domínio não contém pontos incorporados ou não começa com um ponto.

Por quê? O documento indica que precisa fazer algo com segurança. Devo admitir que não li toda a especificação (pode fazê-lo mais tarde), mas parece um pouco estranho. Com base nisso, seria impossível definir cookies no host local.

Jan Zich
fonte
14
Thread de 6 anos e isso ainda é um problema. Estou usando o Chrome v40. Veja aqui .
Gaui
5
Chrome 43 ... ainda é um bug.
Evan Carroll
4
Chrome 54 aqui, não resolvido
Vahid Amiri
6
Chrome 73 .. ainda está enfrentando o mesmo problema. :(
Code_Crash 21/03/19
2
Alguém poderia resolver isso? Ainda enfrentando o mesmo ***, veja esta resposta SO #
Bonjour123

Respostas:

236

Por design, os nomes de domínio devem ter pelo menos dois pontos; caso contrário, o navegador as considerará inválidas. (Consulte a referência em http://curl.haxx.se/rfc/cookie_spec.html )

Ao trabalhar localhost, o domínio do cookie deve ser totalmente omitido. Apenas definindo-o como ""ou NULLou FALSEem vez de "localhost"não é suficiente.

Para PHP, consulte os comentários em http://php.net/manual/en/function.setcookie.php#73107 .

Se estiver trabalhando com a API Java Servlet, não chame o cookie.setDomain("...")método.

Ralph Buchfelder
fonte
93
Não sei por que todo mundo está adicionando +1 a isso, defino o domínio do cookie como uma string nula, falsa ou vazia, e ele ainda não salva se estiver no host local.
Justin Justin
5
Não vejo nenhum lugar no RFC6265 sobre os dois pontos no domínio: tools.ietf.org/html/rfc6265#section-5.2.3. A Net diz que define ".local" para todos os hosts em seu domínio local. O que parece consistente com a Opera / Safari msdn.microsoft.com/en-us/library/ckch3yd2.aspx
MandoMando
9
@ Justin: Hm, você provavelmente precisará omitir completamente o Domain=parâmetro ao configurar o cookie. Se você acabou de definir o domínio como nulo ou vazio, talvez sua estrutura envie o Domain=parâmetro com esse valor, em vez de omiti-lo? Verifique com, por exemplo, o Firebug.
sleske
2
@ Ralph, um milhão de agradecimentos, essa coisa me deixou louco por algumas horas. Esperançosamente, definir o domínio como nulo (estou em uma pilha de servidores .Net) funciona como um encanto.
Xose Lluis
4
Isto é um pouco mal formulado. "A configuração para uma string nula, falsa ou vazia" deve ler "Não é possível definir a parte do 'domínio' do cookie." Por exemplo, o uso de um teste simples para deixar completamente de fora a seção de domínio do cookie funciona para localhost:((domain && domain !== "localhost") ? ";domain="+domain : "")
L0j1k
34

Concordo amplamente com o @Ralph Buchfelder, mas aqui está uma amplificação disso, ao tentar replicar um sistema com vários subdomínios (como example.com, fr.example.com, de.example.com) na minha máquina local ( OS X / Apache / Chrome | Firefox).

Eu editei o / etc / hosts para apontar alguns subdomínios imaginários para 127.0.0.1:

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

Se estou trabalhando em fr.localexample.com e deixo o parâmetro domain fora, o cookie é armazenado corretamente em fr.localexample.com, mas não é visível nos outros subdomínios.

Se eu usar um domínio de ".localexample.com", o cookie é armazenado corretamente para fr.localexample.com, e é visível em outros subdomínios.

Se eu usar um domínio "localexample.com" ou quando estiver tentando um domínio apenas "localexample" ou "localhost", o cookie não será armazenado.

Se eu usar um domínio "fr.localexample.com" ou ".fr.localexample.com", o cookie será armazenado corretamente em fr.localexample.com e será (corretamente) invisível em outros subdomínios.

Portanto, o requisito de que você precisa de pelo menos dois pontos no domínio parece estar correto, mesmo que eu não possa ver por que deveria ser.

Se alguém quiser tentar isso, aqui está um 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
fonte
30

localhost: você pode usar: domain: ".app.localhost"e funcionará. O parâmetro 'domínio' precisa de 1 ou mais pontos no nome do domínio para definir cookies. Então você pode ter sessões de trabalho em subdomínios localhost tais como: api.app.localhost:3000.

AmpT
fonte
1
Também testado e funcionando no servidor node.js, usando Expresso 3.x, emexpress.session({cookie: { domain: '.app.localhost', maxAge: 24 * 60 * 60 * 1000 }})
ampt
3
ESTE deve ser selecionado como resposta se você estiver usando domínios locais! Colocar um ponto antes do subdomínio corrige meu problema.
Foxhoundn
1
Então, de onde vem esse precedente .app.? Faz parte de algum SPEC? E é aplicável a todos os domínios não conformes (aqueles sem dois pontos)? Além disso, isso funcionará com navegadores antigos? : ^)
user2173353
Ah ... eu entendo agora ... É apenas um truque para enganar os navegadores. ESTÁ BEM.
user2173353
14

Quando um cookie é definido com um domínio explícito de 'localhost', da seguinte maneira ...

Set-Cookie: nome = valor; domínio = host local ; expira = Qui, 16 de julho de 2009 21:25:05 GMT; caminho = /

... os navegadores o ignoram porque ele não inclui pelo menos dois períodos e não é um dos sete domínios de nível superior manipulados especialmente .

... os domínios devem ter pelo menos dois (2) ou três (3) períodos para impedir domínios no formato: ".com", ".edu" e "va.us". Qualquer domínio que falhe em um dos sete domínios especiais de nível superior listados abaixo requer apenas dois períodos. Qualquer outro domínio requer pelo menos três. Os sete domínios especiais de nível superior são: "COM", "EDU", "NET", "ORG", "GOV", "MIL" e "INT".

Observe que o número de períodos acima provavelmente supõe que um período inicial seja necessário. No entanto, esse período é ignorado nos navegadores modernos e provavelmente deve ser ...

pelo menos um (1) ou dois (2) períodos

Observe que o valor padrão para o atributo domain é o nome do host do servidor que gerou a resposta do cookie .

Portanto, uma solução alternativa para os cookies que não estão sendo definidos para o host local é simplesmente não especificar um atributo de domínio e deixar o navegador usar o valor padrão - isso não parece ter as mesmas restrições que um valor explícito no atributo de domínio.

Scott Munro
fonte
Eu não DV, mas acho que o motivo que outros fizeram é porque sua resposta realmente não agrega muito valor. Os dois períodos exigidos e deixar o atributo domínio em branco foram discutidos em outras respostas. Além disso, as coisas que você adicionou sobre um domínio de nível superior parecem estar incorretas. Na minha experiência, isso não é um requisito.
TTT 26/01
@TTT Não tenho certeza se você chegou à parte em minha resposta, onde eu digo que deve levar pelo menos 1 ou dois períodos, dependendo do TLD, porque os períodos iniciais são ignorados? Portanto, forneci alguns antecedentes sobre o problema e acrescentei um ponto que acho que não foi abordado em outro lugar - as regras são diferentes para um domínio explícito e o padrão do navegador. Parece que agrega algum valor para mim.
Scott Munro
1
Deixar o domínio nulo (sem defini-lo) NÃO faz com que o Chrome mantenha o cookie para o host local. Ainda o ignora. Observe que isso se aplica apenas a cookies "permanentes" (que definem uma data de validade), porque ele permanecerá nos cookies "de sessão" do host local (aqueles que não definem uma data de validade).
Triynko
3

Resultados que eu variava de acordo com o navegador.

O Chrome 127.0.0.1 funcionou, mas localhost .localhost e "" não. Firefox- .localhost funcionou, mas localhost, 127.0.0.1 e "" não.

Não testou no Opera, IE ou Safari


fonte
3
Acabei de testar com o Chrome V.22.0.1229.94 m: definir um cookie para o host local sem dar um Domain=parâmetro funciona. Domain=também funciona, mas Domain=localhostnão funciona.
sleske
3

Passei muito tempo solucionando esse problema sozinho.

Usando PHP, e Nada nesta página funcionou para mim. Acabei percebendo no meu código que o parâmetro 'secure' para session_set_cookie_params () do PHP estava sempre sendo definido como TRUE.

Como eu não estava visitando o host local com https, meu navegador nunca aceitaria o cookie. Portanto, modifiquei essa parte do meu código para definir condicionalmente o parâmetro 'secure' com base em $ _SERVER ['HTTP_HOST'] sendo 'localhost' ou não. Trabalhando bem agora.

Espero que isso ajude alguém.

James Jacobson
fonte
2

Se você estiver configurando um cookie de outro domínio (ou seja, você definiu o cookie fazendo uma solicitação de origem cruzada XHR), precisa ter certeza de definir o withCredentialsatributo como true no XMLHttpRequest usado para buscar o cookie, conforme descrito aqui

Aidan Ewen
fonte
sim, mesmo com isso. Ainda não funciona com solicitações entre domínios. Navegador - Safari, IE 11
Rohit Kumar
2

você pode usar localhost.orgou melhor, .localhost.orgele sempre resolverá127.0.0.1

qoomon
fonte
1

Tive sorte muito melhor testando localmente usando 127.0.0.1 como domínio. Não sei por que, mas tive resultados mistos com localhost e .localhost etc.

toby
fonte
1

Nenhuma das correções sugeridas funcionou para mim - definindo como nulo, falso, adicionando dois pontos etc. - não funcionou.

No final, acabei de remover o domínio do cookie, se for localhost e que agora funciona para mim no Chrome 38 .

Código anterior (não funcionou):

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

Novo código (agora 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
fonte
1

Eu tive o mesmo problema e o corrigi colocando 2 pontos no nome do cookie, sem especificar nenhum domínio.

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

Parece haver um problema quando você usa https://<local-domain>e depois http://<local-domain>. O http://site não envia cookies com solicitações depois que o https://site os define. Forçar o recarregamento e limpar o cache não ajuda. Somente a limpeza manual de cookies funciona. Além disso, se eu limpá-los na https://página, a http://página começará a funcionar novamente.

Parece estar relacionado a "Cookies seguros estritos". Boa explicação aqui . Foi lançado no Chrome 58 em 19/04/2017.

Parece que o Chrome de fato registra cookies seguros e não seguros, pois mostrará os cookies corretos dependendo do protocolo da página ao clicar no ícone da barra de endereço.

Mas Developer tools > Application > Cookiesnão mostrará um cookie não seguro quando houver um cookie seguro com o mesmo nome para o mesmo domínio, nem enviará o cookie não seguro com quaisquer solicitações. Parece um bug do Chrome ou, se esse comportamento for esperado, deve haver alguma maneira de exibir os cookies seguros quando em uma httppágina e uma indicação de que eles estão sendo substituídos.

A solução alternativa é usar cookies nomeados diferentes, dependendo se eles são para um site http ou site https, e nomeá-los específicos para seu aplicativo. Um __Secure-prefixo indica que o cookie deve ser estritamente seguro e também é uma boa prática, porque o seguro e o não seguro não colidem. Existem outros benefícios para prefixos também.

O uso de /etc/hostsdomínios diferentes para acesso https vs. http também funcionaria, mas uma https://localhostvisita acidental impedirá que cookies com os mesmos nomes funcionem nos http://localhostsites - portanto, essa não é uma boa solução alternativa.

Arquivei um relatório de bug do Chrome .

vaughan
fonte
0

document.cookie = nome do valor + "=" + valor + ";" + expira + "; domínio =; caminho = /";

este "domínio =; caminho = /"; assumirá um domínio dinâmico, pois seu cookie funcionará no subdomínio. se você quiser testar no localhost ele funcionará

Abhishek SInha
fonte
0

Nenhuma das respostas aqui funcionou para mim. Corrigi-o colocando meu PHP como a primeira coisa na página.

Como outros cabeçalhos, os cookies devem ser enviados antes de qualquer saída do seu script (esta é uma restrição de protocolo). Isso requer que você faça chamadas para essa função antes de qualquer saída, incluindo as tags e, além de qualquer espaço em branco.

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

john ktejik
fonte
que não tem nada a ver com o problema, isso não significa cometer o erro de enviar qualquer outra saída para os cabeçalhos
Marnes
0

Eu estava brincando um pouco.

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

funciona no Firefox e Chrome a partir de hoje. No entanto, não encontrei uma maneira de fazê-lo funcionar com curl. Tentei Host-Header e --resolve, sem sorte, qualquer ajuda apreciada.

No entanto, ele funciona em curl, se eu definir como

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

em vez de. (O que não funciona com o Firefox.)

Micha
fonte
0

Outro detalhe importante, expira = deve usar o seguinte formato de data e hora: Wdy, DD-Mon-AAAA HH: MM: SS GMT ( RFC6265 - Seção 4.1.1 ).

Set-Cookie:
  name=value;
  domain=localhost;
  expires=Thu, 16-07-2019 21:25:05 GMT;
  path=/
Tralamazza
fonte
5
-1 A especificação atual para cookies é RFC 6265, tools.ietf.org/html/rfc6265 , que declara explicitamente que são permitidos anos de 4 dígitos. Portanto, é uma má idéia usar anos de 2 dígitos, que diferentes navegadores interpretarão de maneira diferente.
sleske
Corrigir. Ref RFC6265 seção 4.1.1
Zen Cart
4
Correto, mas em junho de 2011 eu não encontrei este RFC. Portanto, enquanto essas informações estão incorretas, quando escrevi não eram.
Tralamazza 9/10/12
4
Não leve a sério, as coisas mudam e todos precisamos ajudar a garantir que as respostas permaneçam atualizadas. Atualize sua resposta com as informações mais recentes que a @sleske forneceu e agradeça a ele por sua ajuda.
Matthew Purdon
0

Após muita experimentação e leitura de vários posts, isso funcionou. Eu poderia definir vários cookies, lê-los novamente e definir o tempo negativo e excluí-los.

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
fonte
0

A única coisa que funcionou para mim foi definir Path=/ o biscoito.

Além disso, o valor padrão de um atributo de caminho parece ser diferente de navegadores para navegadores, embora eu tenha testado apenas dois deles (Firefox e Chrome).

O Chrome tenta definir um cookie como está; se o pathatributo for omitido no Set-Cookiecabeçalho, ele não será armazenado e ignorado.

No entanto, o Firefox armazena um cookie mesmo sem um pathatributo explícito . É só configurá-lo com o caminho solicitado; meu URL de solicitação era /api/v1/userse o caminho era definido /api/v1automaticamente.

De qualquer forma, os dois navegadores funcionavam quando pathera definido como /mesmo sem um domínio explícito, Domain=localhostou seja, algo assim. Portanto, existem algumas diferenças na maneira como cada navegador lida com cookies.

이준형
fonte