Set-Cookie в HTTP-заголовке игнорируется с помощью AngularJS
Я работаю над приложением, основанным на AngularJS на стороне клиента и Java для моего API (Tomcat + Jersey for WS) на стороне сервера.
Некоторый путь моего API ограничен, если у пользователя нет сеанса, возвращается статус ответа 401. На стороне клиента перехватывается статус 401 http для перенаправления пользователя на страницу входа.
После аутентификации пользователя я создаю сеанс на стороне сервера
httpRequest.getSession(true);
и ответ, отправленный клиенту, имеет команду Set-cookie в заголовке:
Set-Cookie:JSESSIONID=XXXXXXXXXXXXXXXXXXXXX; Domain=localhost; Path=/api/; HttpOnly
Проблема в том, что cookie никогда не ставится на стороне клиента. Когда я проверяю файл cookie для домена localhost, он пуст, поэтому в следующих запросах нет этого файла cookie в заголовке и на стороне клиента, все еще не может получить доступ к ограниченному пути моего API.
Клиент и сервер находятся в одном домене, но у них нет одинакового пути и одного и того же номера порта:
Клиент: http://localhost:8000/app/index.html
Сервер: http://localhost:8080/api/restricted/
Дополнительная информация: CORS включен с обеих сторон:
"Access-Control-Allow-Methods", "GET, POST, OPTIONS"
"Access-Control-Allow-Origin", "*"
"Access-Control-Allow-Credentials", true
Любая идея создания Set-cookie работает правильно?
Это проблема, связанная с AngularJS?
Ответы
Ответ 1
Я нашел проблему в AngularJS, которая помогает мне двигаться вперед.
Кажется, что "Access-Control-Allow-Credentials" : true
не было установлено на стороне клиента.
Инструкция $httpProvider.defaults.withCredentials = true
была проигнорирована.
Я заменяю вызов $resource простым $http-вызовом с {withCredentials: true} в параметре конфигурации.
Ответ 2
Мне удалось решить проблему, очень похожую на вашу.
Моя игра! backend попытался установить сессию Cookie, которую я не смог поймать в Angular или сохранить через браузер.
На самом деле решение включало немного этого и немного того.
Предполагая, что вы решили исходную проблему, которая может быть решена только путем добавления определенного домена в Access-Control-Allow-Origin и удаления подстановочного знака, следующие шаги:
-
Вам нужно удалить HTTP-Only из заголовка Set-Cookie
, иначе вы никогда не сможете получить cookie, сгенерированный вашим кодом Angular
Эта настройка уже работает в Firefox, но не в Chrome
-
Чтобы заставить его работать и для Chrome, вам необходимо:
a) отправить другой домен из локального хоста в файл cookie, используя домен, на котором размещены ваши WS. Вы даже можете использовать подстановочные знаки, такие как .domain.com
вместо ws.domain.com
b), тогда вам нужно будет позвонить в домен, указанный вами в файле cookie, иначе Chrome не сохранит ваш файл cookie
[optional] Я бы удалил этот путь /api
в пользу /
И это должно к трюку.
Надеюсь, что сможем помочь.
Ответ 3
В своем почтовом запросе на стороне клиента обязательно добавьте следующее:
Для запросов jQuery ajax:
$.ajax({
url: "http://yoururlgoeshere",
type: "post",
data: "somedata",
xhrFields: {
withCredentials: true
}
});
Ответ 4
Добавление HttpOnly означает, что браузер не должен позволять плагинам и JavaScript видеть cookie. Это недавнее соглашение о безопасном просмотре. Должен использоваться для J_SESSIONID, но, возможно, не здесь.
Ответ 5
Вам нужна работа как на стороне сервера, так и на стороне клиента.
Client
Установите $http
config withCredentials
в true
одним из следующих способов:
-
По запросу
var config = {withCredentials: true};
$http.post(url, config);
-
Для всех запросов
angular.module("your_module_name").config(['$httpProvider',
function($httpProvider) {
$httpProvider.interceptors.push(['$q',
function($q) {
return {
request: function(config) {
config.withCredentials = true;
return config;
}
};
}
]);
}
]);
Сервер
Задайте заголовок ответа Access-Control-Allow-Credentials
на true
.
Ответ 6
Просто решил проблему вроде этого.
Я делал это и не работал...:
$cookies.put('JSESSIONID', response.data);
Cookies сохраняются в браузере, но когда я отправил новый запрос, все куки были отправлены вне моего. (мой файл cookie - JSESSIONID)
тогда я смотрю в хромовом инспекторе, и я нашел это:
![Моя сессия - это JsessionID]()
ПРОБЛЕМА - ЭТО НЕ ПРАВИЛЬНОЕ ПУТЬ!!!
то я попробовал это, и мои файлы cookie были отправлены. ура!
$cookies.put('JSESSIONID', response.data, {'path':'/'});
Я не знаю, было ли это ваше дело, но это сработало для меня.
привет!