Je travaille sur une application basée sur AngularJS côté client et sur 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, l'état de la réponse renvoyé est 401. Du côté client, les états 401 http sont interceptés 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);
Set-Cookie: JSESSIONID = XXXXXXXXXXXXXXXXXXXXX; Domain = localhost; Path =/api /; HttpOnly
Le problème est que le cookie n'est jamais placé du côté client. Lorsque j'inspecte le cookie du domaine localhost, celui-ci est vide. Par conséquent, les demandes suivantes n'ont pas ce cookie dans leur en-tête et le client ne peut toujours pas accéder au chemin d'accès restreint de mon API.
Le client et le serveur sont sur le même domaine mais ils n'ont pas le même chemin et le même numéro de port:
Client : http://localhost:8000/app/index.html
Serveur: http://localhost:8080/api/restricted/
Informations complémentaires: CORS est activé des deux côtés:
"Méthodes d'accès-de contrôle-autorisation", "GET, POST, OPTIONS" "Origine de contrôle d'accès", "*" "Informations d'authentification de contrôle d'accès", vrai
Une idée pour que le cookie Set fonctionne correctement? Est-ce un problème lié à AngularJS?
J'ai trouvé un numéro dans AngularJS qui m'aide à avancer.
Il paraît que "Access-Control-Allow-Credentials" : true
n'était pas défini du côté client. Instruction $httpProvider.defaults.withCredentials = true
a été ignoré.
Je remplace l’appel $ resource par un simple appel $ http avec {withCredentials: true} dans le paramètre config.
J'ai réussi à résoudre un problème très similaire au vôtre. Mon jeu! backend a essayé de définir un cookie de session que je ne pouvais pas attraper Angular ou stocker via un navigateur.
En fait, la solution impliquait un peu de ceci et un peu de cela.
En supposant que vous ayez résolu le problème initial, qui ne peut être résolu qu'en ajoutant un domaine spécifique à Access-Control-Allow-Origin et en supprimant le caractère générique, procédez comme suit:
Vous devez supprimer le HTTP-Only du Set-Cookie
en-tête, sinon vous ne pourrez jamais recevoir un cookie "généré" par votre angular
Cette configuration fonctionnera déjà dans Firefox, mais pas dans Chrome
Pour que cela fonctionne avec Chrome aussi, vous devez:
a) envoyez un domaine différent de localhost dans le cookie, en utilisant le domaine pour lequel vos WS sont "hébergés". Vous pouvez même utiliser des jokers comme .domain.com
au lieu de ws.domain.com
b) vous devrez ensuite appeler le domaine que vous avez spécifié dans le cookie, sinon Chrome ne stockera pas votre cookie
[facultatif] Je retirerais ce /api
chemin en faveur d'un /
Et cela devrait faire l'affaire.
J'espère avoir été utile
Dans votre demande de publication côté client, veillez à ajouter les éléments suivants:
Pour les requêtes jquery ajax:
$.ajax({
url: "http://yoururlgoeshere",
type: "post",
data: "somedata",
xhrFields: {
withCredentials: true
}
});
Avec le service $ http de Angular:
$http.post("http://yoururlgoeshere", "somedata", {
withCredentials: true
});
L'addition HttpOnly signifie que le navigateur ne doit pas laisser les plugins et JavaScript voir le cookie. Ceci est une convention récente pour une navigation plus sûre. Devrait être utilisé pour J_SESSIONID mais peut-être pas ici.
Vous devez travailler à la fois côté serveur et côté client.
Client
Ensemble $http
config withCredentials
à true
de l’une des manières suivantes:
Par reqûette
var config = {withCredentials: true};
$http.post(url, config);
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éfinir l'en-tête de réponse Access-Control-Allow-Credentials
à true
.
Je viens de résoudre un problème comme celui-ci.
Je faisais ça et je ne travaillais pas ...:
$cookies.put('JSESSIONID', response.data);
Les 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)
alors je regarde dans le chrome inspecteur et j'ai trouvé ceci:
LE PROBLÈME IS C'É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.
cordialement!