Depois de fazer login em $.ajax()
um site, estou tentando enviar uma segunda $.ajax()
solicitação para esse site - mas quando verifico os cabeçalhos enviados usando o FireBug, não há nenhum cookie de sessão sendo incluído na solicitação.
O que estou fazendo errado?
Respostas:
As chamadas AJAX apenas enviam cookies se o URL que você está chamando estiver no mesmo domínio que o seu script de chamada.
Este pode ser um problema entre domínios.
Talvez você tenha tentado ligar para um URL
www.domain-a.com
enquanto o script de chamada estava ativadowww.domain-b.com
(em outras palavras: você fez uma chamada entre domínios; nesse caso, o navegador não envia cookies para proteger sua privacidade).Nesse caso, suas opções são:
Esse proxy pode então ser configurado por você para aceitar um nome de cookie e um parâmetro de valor que pode ser enviado ao domínio-a. Mas, para que isso funcione, você precisa saber o nome do cookie e avaliar seu servidor no domínio - a quer autenticação.
Ainda bem que isso ajudou um pouco.
fonte
path=/something
e está solicitando a página/another
, o cookie não será enviado. Quando você solicita a página,/something
o cookie será enviado conforme o esperado. Portanto, verifique o código que define o cookie também.Estou operando no cenário entre domínios. Durante o login, o servidor remoto está retornando o cabeçalho Set-Cookie junto com
Access-Control-Allow-Credentials
set como true.A próxima chamada ajax para o servidor remoto deve usar esse cookie.
Os CORS
Access-Control-Allow-Credentials
estão lá para permitir o registro entre domínios. Verifique https://developer.mozilla.org/En/HTTP_access_control para obter exemplos.Para mim, parece um bug no JQuery (ou pelo menos um recurso na próxima versão).
ATUALIZAR:
Os cookies não são definidos automaticamente a partir da resposta AJAX (citação: http://aleembawany.com/2006/11/14/anatomy-of-a-well-designed-ajax-login-experience/ )
Por quê?
Você não pode obter o valor do cookie da resposta para defini-lo manualmente ( http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-getresponseheader )
Estou confuso..
Deve haver uma maneira de pedir
jquery.ajax()
para definir oXMLHttpRequest.withCredentials = "true"
parâmetro.RESPOSTA: Você deve usar o
xhrFields
parâmetro http://api.jquery.com/jQuery.ajax/O exemplo na documentação é:
Também é importante que o servidor responda corretamente a essa solicitação. Copiando aqui ótimos comentários de @ Frédéric e @Pebbl:
Important note: when responding to a credentialed request, server must specify a domain, and cannot use wild carding. The above example would fail if the header was wildcarded as: Access-Control-Allow-Origin: *
Então, quando a solicitação é:
O servidor deve responder com:
Caso contrário, a carga útil não será retornada ao script. Consulte: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials
fonte
Important note: when responding to a credentialed request, server must specify a domain, and cannot use wild carding. The above example would fail if the header was wildcarded as: Access-Control-Allow-Origin: *
developer.mozilla.org/en-US/docs/Web/HTTP/...Usando
como parte da minha chamada jQuery ajax era apenas parte da solução. Eu também precisava ter os cabeçalhos retornados na resposta OPTIONS do meu recurso:
Era importante que apenas uma "origem" permitida estivesse no cabeçalho de resposta da chamada OPTIONS e não "*". Consegui isso lendo a origem da solicitação e preenchendo-a novamente na resposta - provavelmente contornando o motivo original da restrição, mas, no meu caso de uso, a segurança não é fundamental.
Eu pensei que vale a pena mencionar explicitamente o requisito para apenas uma origem, pois o padrão W3C permite uma lista separada por espaço - mas o Chrome não! http://www.w3.org/TR/cors/#access-control-allow-origin-response-header NB o bit "na prática".
fonte
Coloque isso na sua função init:
Vai funcionar.
fonte
Já existem muitas respostas boas para essa pergunta, mas achei útil esclarecer o caso em que você espera que o cookie da sessão seja enviado porque o domínio do cookie corresponde, mas não está sendo enviado porque a solicitação AJAX é sendo feito para um subdomínio diferente. Nesse caso, tenho um cookie atribuído ao domínio * .mydomain.com e pretendo que ele seja incluído em uma solicitação AJAX para different.mydomain.com ". Por padrão, o cookie não é enviado. Você não precisa desabilitar o HTTPONLY no cookie da sessão para resolver esse problema. Você só precisa fazer o que sugeriu wombling ( https://stackoverflow.com/a/23660618/545223 ) e fazer o seguinte.
1) Adicione o seguinte ao seu pedido de ajax.
2) Adicione o seguinte aos seus cabeçalhos de resposta para obter recursos nos diferentes subdomínios.
fonte
Depois de experimentar as outras soluções e ainda não fazê-lo funcionar, descobri qual era o problema no meu caso. Alterei contentType de "application / json" para "text / plain".
fonte
Eu estava tendo o mesmo problema e, ao fazer algumas verificações, meu script simplesmente não estava recebendo o cookie sessionid.
Eu descobri olhando para o valor do cookie sessionid no navegador que minha estrutura (Django) estava passando o cookie sessionid com o HttpOnly como padrão. Isso significava que os scripts não tinham acesso ao valor sessionid e, portanto, não o passavam junto com os pedidos. É ridículo que HttpOnly seja o valor padrão quando tantas coisas usam o Ajax, o que exigiria restrição de acesso.
Para corrigir isso, alterei uma configuração (SESSION_COOKIE_HTTPONLY = False), mas em outros casos pode ser um sinalizador "HttpOnly" no caminho do cookie
fonte
Se você estiver desenvolvendo em
localhost
ou uma porta no host local, comolocalhost:8080
, além das etapas descritas nas respostas acima, também precisará garantir que não esteja passando um valor de domínio no cabeçalho Set-Cookie.Você não pode definir o domínio
localhost
no cabeçalho Set-Cookie - isso está incorreto - apenas omita o domínio.Veja Cookies no host local com domínio explícito e Por que o asp.net não cria cookies no host local?
fonte
Apenas meus 2 centavos na configuração do problema de cookie PHPSESSID quando estiver no host local e no ambiente de desenvolvimento. Eu faço a chamada AJAX para o meu ponto de extremidade da API REST no locahost. Digamos que seu endereço seja
mysite.localhost/api/member/login/
(host virtual no meu ambiente de desenvolvimento).Quando faço essa solicitação no Postman , as coisas correm bem e o PHPSESSID é definido com a resposta.
Quando solicito esse endpoint via AJAX na página em proxy do Browsersync (por exemplo,
122.133.1.110:3000/test/api/login.php
na linha de endereço do meu navegador, veja se o domínio é diferentemysite.localhost
), o PHPSESSID não aparece entre os cookies.Quando faço esse pedido diretamente da página no mesmo domínio (por exemplo
mysite.localhost/test/api/login.php
), o PHPSESSID está definido corretamente.Portanto, este é um problema de cookies de solicitação de origem de origem cruzada, conforme mencionado na resposta @flu acima
fonte
Adicionando meu cenário e solução, caso isso ajude outra pessoa. Encontrei um caso semelhante ao usar APIs RESTful. Meu servidor da Web que hospeda arquivos HTML / Script / CSS e APIs de exposição do Application Server foram hospedados no mesmo domínio. No entanto, o caminho foi diferente.
usou o abc.js que define o cookie chamado mycookie
para o qual as chamadas da API foram feitas
Eu estava esperando o cookie em meudomínio / webapis / servicename e tentei lê-lo, mas ele não estava sendo enviado. Depois de ler o comentário da resposta, verifiquei na ferramenta de desenvolvimento do navegador que o caminho do mycookie estava definido como "/ páginas da web " e, portanto, não estava disponível na chamada de serviço para
Então, ao definir o cookie do jquery, foi o que eu fiz -
fonte
Talvez não esteja 100% respondendo à pergunta, mas me deparei com esse tópico na esperança de resolver um problema de sessão ao postar ajax um upload de arquivo do gerenciador de ativos do editor innovastudio. Eventualmente, a solução foi simples: eles têm um flash-uploader. Desativando isso (configuração
em asset.php) e as luzes começaram a piscar novamente.
Como esses problemas podem ser muito difíceis de depurar, descobri que colocar algo como o seguinte no manipulador de upload definirá você (bem, eu neste caso) no caminho certo:
Mergulhei no registro e rapidamente localizei a sessão ausente, onde nenhum cookie foi enviado.
fonte
session_name(isset($_GET['sess']) ? $_GET['sess'] : null);session_start();
desta forma, eles teriam uma coisa trabalhando