ti-enxame.com

Set-Cookie no cabeçalho HTTP é ignorado com o AngularJS

Eu estou trabalhando em um aplicativo baseado em AngularJS no lado do cliente e Java para minha API (Tomcat + Jersey para WS) no lado do servidor.

Algum caminho da minha API é restrito, se o usuário não tiver uma sessão, o status de resposta retornado será 401. No lado do cliente, o status http 401 é interceptado para redirecionar o usuário para a página de login.

Depois que o usuário é autenticado, eu crio uma sessão no lado do servidor

httpRequest.getSession (true);
 Set-Cookie: JSESSIONID = XXXXXXXXXXXXXXXXXXXXX; Domínio = localhost; Caminho =/api /; HttpOnly 

O problema é que o cookie nunca é colocado no lado do cliente. Quando eu inspeciono o cookie para o domínio localhost ele está vazio, então as próximas solicitações não têm esse cookie no cabeçalho e o lado do cliente ainda não conseguiu acessar o caminho restrito da minha API.

O cliente e o servidor estão no mesmo domínio, mas não possuem o mesmo caminho e o mesmo número de porta:

Cliente: http://localhost:8000/app/index.html

Servidor: http://localhost:8080/api/restricted/

Informações adicionais: o CORS está ativado em ambos os lados:

"Access-Control-Permitir-Métodos", "GET, POST, OPTIONS" 
 "Acesso-Controle-Permitir-Origem", "*" 
 "Acesso-Controle-Permitir-Credenciais", verdade

Qualquer ideia para fazer o Set-cookie funciona corretamente? É uma questão relacionada ao AngularJS?

67
Romain Lefrancois

Eu encontrei um problema no AngularJS que me ajuda a seguir em frente.

Parece que "Access-Control-Allow-Credentials" : true não foi definido no lado do cliente. A instrução $httpProvider.defaults.withCredentials = true foi ignorada.

Eu substituo $ resource call por uma simples chamada $ http com {withCredentials: true} no parâmetro config.

21
Romain Lefrancois

Eu consegui resolver um problema muito parecido com o seu. Meu jogo! backend tentou definir uma sessão Cookie que eu não pude pegar em Angular ou armazenar via browser.

Na verdade, a solução envolveu um pouco disso e um pouco disso.

Supondo que você tenha resolvido o problema inicial, que pode ser resolvido apenas adicionando um domínio específico ao Access-Control-Allow-Origin e removendo o curinga, os próximos passos são:

  1. Você tem que remover o HTTP-Only do cabeçalho Set-Cookie, caso contrário você nunca será capaz de receber um cookie "gerado" pelo seu código angular
    Essa configuração já funcionará no Firefox, embora não no Chrome

  2. Para que isso funcione também no Chrome, você precisa:

    a) enviar um domínio diferente do localhost no cookie, usando o domínio que seu WS está "hospedado". Você pode até usar curingas como .domain.com em vez de ws.domain.com

    b) então você precisará fazer uma chamada para o domínio que você especificou no cookie, caso contrário o Chrome não armazenará seu cookie

    [opcional] Eu removeria esse caminho /api em favor de /


E isso deve ao truque.
Espero ter sido de alguma ajuda

17
domokun

Em sua solicitação de postagem no lado do cliente, adicione o seguinte:

Para solicitações de jquery ajax:

$.ajax({
  url: "http://yoururlgoeshere",
  type: "post",
  data: "somedata",
  xhrFields: {
    withCredentials: true
  }
});

Com o serviço $ http do Angular:

$http.post("http://yoururlgoeshere", "somedata", {
  withCredentials: true
});
13
Teliov

A adição HttpOnly significa que o navegador não deve permitir que plugins e JavaScript vejam o cookie. Esta é uma convenção recente para navegação segura. Deve ser usado para J_SESSIONID, mas talvez não esteja aqui.

7
Joop Eggen

Você precisa trabalhar no servidor e no lado do cliente.

cliente

Configure $http config withCredentials para true de uma das seguintes maneiras:

  1. Por pedido

    var config = {withCredentials: true};
    $http.post(url, config);
    
  2. Para todos os pedidos

    angular.module("your_module_name").config(['$httpProvider',
      function($httpProvider) {
        $httpProvider.interceptors.Push(['$q',
          function($q) {
            return {
              request: function(config) {
                config.withCredentials = true;
                return config;
              }
            };
          }
        ]);
      }
    ]);
    

servidor

Defina o cabeçalho de resposta Access-Control-Allow-Credentials para true.

7
Edmond Chui

Apenas resolvi um problema como esse.

Eu estava fazendo isso e não trabalhando ...:

  $cookies.put('JSESSIONID', response.data);

Os cookies são salvos no navegador, mas quando eu enviei uma nova solicitação, todos os cookies foram enviados exceto o meu. (meu cookie é JSESSIONID)

então eu olho no inspetor chrome e achei isso: My session are the JsessionID

O PROBLEMA IS QUE NÃO FOI O CAMINHO CORRETO !!!

então eu tentei isso e meus cookies foram enviados. yay! :

$cookies.put('JSESSIONID', response.data, {'path':'/'});

Eu não sei se esse é o seu caso, mas isso funcionou para mim.

saudações!

1
Nicolas Mastromarino