Не удается получить файлы cookie, установленные сервером Play Framework, в Angular $ http call?

0

Я пытаюсь получить файлы cookie, которые я устанавливаю на сервере, используя PlayFramework:

response().setHeader(SET_COOKIE, AppConstants.COOKIE_USER_SESSIONID+"="+appSession.getSid());

в угловом приложении, но я не в состоянии.

Если я использую клиент Advanced Rest, я получаю заголовок SetCookie и файлы cookie устанавливаются в следующем вызове. Однако, когда я вызываю одно и то же api через мое угловое приложение, я не могу получить заголовок в ответе и, следовательно, не куки для приложения.

Вот что я уже пробовал:

  1. переименование среды с localhost на xyz.com, так как я читал несколько ответов, что файлы cookie не работают на localhost.
  2. Попробовал api создать отдельный клиент для отдыха, смог успешно получить заголовок, так что API выглядит хорошо для меня.

Должен быть некоторый улов в угловом коде, который я не могу понять. Любая помощь по этому поводу высоко ценится. Благодарю.

Угловые фрагменты кода:

LoginController:

angular.module('wratApp')
  .controller('LoginCtrl', function (postService, wratSettings, wratRoutes, $location, $cookies) {
    $("#header").hide();

    this.user= {};

    this.logUserin = function(){
        console.log("User: " + this.user.email + " & pwd: " + this.user.pwd);
        var payLoad = {};
        payLoad.ldap = this.user.email;
        payLoad.pwd = this.user.pwd;
        postService.postPromise(wratRoutes(wratSettings).POST_USER_LOGIN(),payLoad)
          .then(function(){ //login success
              console.log("login success");
              $location.path(wratRoutes().CLIENT_HOME());
          }, function(){ //error in login
              console.log("Login failed");
          })
        ;
    }

  });

PostService:

angular.module('wratApp')
  .factory('postService', function ($http, $q, $cookies, $location) {

    function postService() {

      var self = this;

      self.postPromise = function (uri,payload){

        var deferred = $q.defer();

        $http.post(uri,payload)
          .success(function(data, status, headers, config){
            console.log("Got response cookies: "+$cookies.getAll());
            deferred.resolve(data);
          })
          .error(function(data, status, headers, config){
            if(status == 401){
              angular.forEach($cookies.getAll(), function (v, k) {
                $cookies.remove(k);
              });
              $location.path('/login');
            }else{
              deferred.reject(data);
            }
          });

        return deferred.promise;

      }

    }

    return new postService();
  });

Теперь мой логин успешно завершен, но без файлов cookie, установленных сервером. Кроме того, cookie PlaySession, который каким-то образом отображается в отладчике (установленные вручную из него даже отсутствуют в отладчике), не находится в переменной $ cookie с угловым значением (см. Рисунок ниже).

Изображение 174551

Пожалуйста, предложите, как я могу это решить. Благодарю.

Обновление 1:

Если я запускаю сервер воспроизведения не в режиме отладки, файлы cookie соответствующим образом отправляются сервером. Это проблема с угловым приложением, когда в следующем вызове он не переносит значения из заголовка Set-Cookie в файлы cookie для следующего вызова. Возможно, это и глупая ошибка на моем конце. Пожалуйста, посмотрите, можете ли вы помочь мне разобраться.

Ответ сервера/логин:

HTTP/1.1 200 OK
Vary: Origin
Set-Cookie: sid=1e6823e24554598b0521ca5f64d7746b; Path=/
Set-Cookie: PLAY_SESSION=953d9d5730bf1b77cccaadef6b78c209e59d924b-sid=1e6823e24554598b0521ca5f64d7746b; Path=/; HTTPOnly
Content-Type: application/json; charset=utf-8
Access-Control-Allow-Origin: http://wrat.com:9009
Access-Control-Allow-Methods: OPTIONS, GET, POST
Access-Control-Allow-Credentials: true
Date: Thu, 24 Sep 2015 22:27:03 GMT
Content-Length: 429

Следующий запрос, который должен содержать cookie, но без файлов cookie :-(:

GET /products/all HTTP/1.1
Host: wrat.com:9000
Accept: application/json, text/plain, */*
Origin: http://wrat.com:9009
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36
Referer: http://wrat.com:9009/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8

Снятие тега платформы Play, так как это не проблема с воспроизведением.

  • 0
    Это похоже на проблему только для http, но это не так. Я проследил, чтобы куки были получены на html-странице соответствующим образом через заголовок Set-Cookie к ответу. Однако реальная проблема заключается в том, что при следующем вызове сервера значения не устанавливаются из заголовка в файлы cookie. Я бы обновил вопрос, чтобы отразить это.
Теги:
cookies

1 ответ

1

Добавление опции withCredentials в вызовы $ http работало для меня и разрешило проблему.

$http.post(uri,payload, {withCredentials: true})

Проблема связана с вызовами ajax, где, если флаг withCredentials не правдоподобен как на сервере, так и на клиенте, cookie, установленные сервером, не поддерживаются для вызовов с перекрестным происхождением. Следовательно, это полностью игнорировало файлы cookie, которые я устанавливал с сервера.

Текст из следующего вопроса помог решить проблему:

Почему метод jQuery.ajax() не отправляет мой cookie сеанса?

из:

Я работаю в междоменном сценарии. Во время входа в систему удаленный сервер возвращает заголовок Set-Cookie вместе с параметром Allow-Access-Control-Credentials равным true.

Следующий вызов ajax для удаленного сервера должен использовать этот файл cookie.

CORS Access-Control-Allow-Credentials позволяет осуществлять междоменное протоколирование. Для примера рассмотрите https://developer.mozilla.org/En/HTTP_access_control.

Для меня это похоже на ошибку в JQuery (или, по крайней мере, функцию, которая будет в следующей версии).

ОБНОВИТЬ:

Файлы cookie автоматически не устанавливаются из ответа AJAX (ссылка: http://aleembawany.com/2006/11/14/anatomy-of-a-well-designed-ajax-login-experience/)

Зачем?

Вы не можете получить значение cookie из ответа, чтобы установить его вручную (http://www.w3.org/TR/XMLHttpRequest/#dom-xmlhttprequest-getresponseheader)

Я смущен..

Должен существовать способ задать jquery.ajax() для установки параметра XMLHttpRequest.withCredentials = "true".

ОТВЕТ: Вы должны использовать параметр xhrFields для http://api.jquery.com/jQuery.ajax/

Пример в документации:

$.ajax({url: a_cross_domain_url, xhrFields: {withCredentials: true}}); Важно также, чтобы сервер правильно ответил на этот запрос. Копирование здесь замечательных комментариев от @Frédéric и @Pebbl:

Важное примечание: при ответе на запрос с полномочиями сервер должен указать домен и не может использовать wild carding. Вышеприведенный пример потерпит неудачу, если заголовок был подстановочным знаком: Access-Control-Allow-Origin: *

Поэтому, когда запрос:

Происхождение: http://foo.example Cookie: pageAccess = 2 Сервер должен ответить:

Access-Control-Allow-Origin: http://foo.example Access-Control-Allow-Credentials: true

[полезная нагрузка] В противном случае полезная нагрузка не будет возвращена скрипту. См. Https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials.

  • 0
    Спасибо, это помогло мне решить ту же проблему, что и ваша

Ещё вопросы

Сообщество Overcoder
Наверх
Меню