Set-Cookie dans L'en-tête HTTP est ignoré avec AngularJS

je travaille sur une application basée sur AngularJS côté client et Java pour mon API (Tomcat + Jersey pour WS) côté serveur.

certains chemins de mon API sont limités, si l'utilisateur n'a pas de session, le statut de réponse retourné est 401. Côté client, le statut http 401 est intercepté pour rediriger l'utilisateur vers la page de connexion.

une fois l'utilisateur authentifié, je crée une session côté serveur

httpRequest.getSession(true);
et la réponse de l'envoyer au client de n'avoir le Set-cookie instruction dans son en-tête :
Set-Cookie:JSESSIONID=XXXXXXXXXXXXXXXXXXXXX; Domain=localhost; Path=/api/; HttpOnly

le problème est que le cookie n'est jamais placé du côté du client. Quand j'inspecte le cookie pour le domaine localhost, il est vide, donc les requêtes suivantes n'ont pas ce cookie dans leur en-tête et le côté client ne peut toujours pas accéder au chemin restreint de mon API.

le client et Le serveur sont sur le même domaine, mais ils n'ont pas le même parcours et le même numéro de port :

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

serveur: http://localhost:8080/api/restricted/

informations supplémentaires : CORS est activé des deux côtés:

"Access-Control-Allow-Methods", "GET, POST, OPTIONS"
"Access-Control-Allow-Origin", "*"
"Access-Control-Allow-Credentials", true

une idée pour faire le Set-cookie fonctionne correctement ? Est-ce une question liée à AngularJS ?

67
demandé sur domokun 2013-02-22 18:07:25

6 réponses

j'ai trouvé un question dans AngularJS qui m'aident à aller de l'avant.

il semble que "Access-Control-Allow-Credentials" : true n'ait pas été placé du côté du client. L'Instruction $httpProvider.defaults.withCredentials = true a été ignorée.

je remplace $resource call par un simple $http call avec {withCredentials:true} dans le paramètre config.

20
répondu Romain Lefrancois 2017-03-14 13:10:45

j'ai réussi à résoudre un problème très similaire au vôtre. Mon Jeu! backend a essayé de configurer un Cookie de session que je ne pouvais pas attraper dans Angular ou stocker via le navigateur.

en Fait, la solution: un peu de ceci et un peu de cela.



en supposant que vous avez résolu le problème initial, qui ne peut être résolu qu'en ajoutant un domaine spécifique à L'Access-Control-Allow-Origin et en supprimant le Joker, les prochaines étapes sont les suivantes:

  1. vous devez supprimer le HTTP-seulement de l'en-tête Set-Cookie , sinon vous ne serez jamais en mesure de recevoir un cookie "généré" par votre code angulaire

    cette configuration fonctionnera déjà dans Firefox, mais pas dans Chrome

  2. "
  3. pour le faire fonctionner pour Chrome aussi, vous devez:

    a) envoyer un domaine différent de localhost dans le cookie, en utilisant le domaine que vos WS sont "hébergés". Vous pouvez même utiliser des caractères génériques comme .domain.com au lieu de ws.domain.com

    B) ensuite, vous devrez faire un appel au domaine que vous avez spécifié dans le cookie, sinon Chrome ne stockera pas votre cookie

    [facultatif] je supprimerais ce /api chemin en faveur d'un /



Et qui doit le truc.

Espère avoir été d'une aide

17
répondu domokun 2013-10-31 10:55:56

dans votre requête post côté client, assurez-vous d'ajouter ce qui suit:

Pour jquery ajax demande:

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

Angulaire de dollars du service http :

$http.post("http://yoururlgoeshere", "somedata", {
  withCredentials: true
});
12
répondu Teliov 2015-11-19 14:34:13

l'ajout HttpOnly signifie que le navigateur ne doit pas laisser les plugins et JavaScript voir le cookie. Il s'agit d'une convention récente pour la navigation securer. Devrait être utilisé pour J_SESSIONID mais peut-être pas ici.

7
répondu Joop Eggen 2013-02-22 14:22:11

vous devez travailler à la fois du côté du serveur et du côté client.

Client

Set $http config withCredentials à true dans l'une des façons suivantes:

  1. par requête

    var config = {withCredentials: true};
    $http.post(url, config);
    
  2. Pour toutes les demandes

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

Serveur

définit l'en-tête de réponse Access-Control-Allow-Credentials à true .

7
répondu Edmond Chui 2017-08-02 16:23:44

vient de résoudre un problème comme celui-ci.

je faisais ça et je ne travaillais pas...:

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

Cookies sont enregistrés dans le navigateur, mais lorsque j'ai envoyé une nouvelle demande, tous les cookies ont été envoyés sauf le mien. (mon cookie est JSESSIONID)

ensuite, je regarde dans l'inspecteur de chrome et j'ai trouvé cette: My session are the JsessionID

LE PROBLÈME EST QUE CE N'ÉTAIT PAS LE BON CHEMIN!!!

alors j'ai essayé ceci et mes cookies ont été envoyés. yay!!! :

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

je ne sais pas si c'est votre cas, mais cela a fonctionné pour moi.

matière de!

1
répondu Nicolas Mastromarino 2016-05-20 20:13:45