Невозможно удалить файл cookie с помощью $cookies AngularJS

Мое веб-приложение сделано так, что когда пользователь входит на сервер, добавляется заголовок Set-Cookie в ответ, например:

Set-Cookie:JSESSIONID=1; Path=/myApp/; Secure

При выходе из системы я пытаюсь удалить этот файл cookie на клиенте (браузере), так как мне все равно, был ли сеанс успешно уничтожен на сервере, если файл cookie удален. Любые затянувшиеся «призрачные» сеансы будут время от времени очищаться на сервере.

Однако мое приложение не может удалить файл cookie JSESSIONID. Скажем, функция выхода из системы была вызвана из https://test.myserver.com/myApp/app/index.html#/mySubPage, и функция выхода из системы делает следующее:

delete $cookies["JSESSIONID"];
$location.path("/login");

Файл cookie не удаляется. Обновление списка файлов cookie на вкладке «Ресурсы» в инструментах разработчика Chrome показывает, что он все еще там. При перезагрузке страницы входа и обновлении списка файлов cookie на вкладке «Ресурсы» файл cookie по-прежнему отображается.

Почему я не могу удалить файл cookie из моего клиента Javascript, если он не является файлом cookie HTTPOnly? Это путь, который вызывает проблемы? Не должно быть, поскольку скрипт выполняется на странице, включенной в путь файла cookie. С файлами cookie на самом деле не так сложно иметь дело, поэтому я прекрасно понимаю, что здесь может быть что-то тривиальное, что я упускаю из виду, но любая помощь будет очень признательна.

ОБНОВЛЕНИЕ:

Я указал неправильный путь к моему приложению в своем исходном сообщении. Теперь он отредактирован, чтобы отразить правильный путь (ну, абстрактно). Оказывается, это была критическая информация для вопроса. AngularJS использует полный относительный путь приложения в качестве атрибута пути всех файлов cookie, которые он создает/удаляет, поэтому, поскольку наш сервер установил для файла cookie путь /myApp/, а приложение работало по относительному пути /myApp/app, Angular пытался удалить прежний файл cookie, которого не существует (чтобы перезаписать или удалить существующий файл cookie, имя, домен и путь должны быть идентичны тем, которые использовались при создании файла cookie).


person Joe Dyndale    schedule 07.01.2013    source источник
comment
Вы включили ngCookies в свой модуль? Например, angular.module('myApp', ['ngCookies'])   -  person asgoth    schedule 07.01.2013
comment
да. Я могу прочитать куки без каких-либо проблем. Я нигде не получаю никаких ошибок, файл cookie просто остается на месте, хотя его нужно было удалить.   -  person Joe Dyndale    schedule 07.01.2013
comment
Вы пробовали использовать $cookieStore.remove(key)?   -  person asgoth    schedule 07.01.2013
comment
Еще одна вещь: происходит ли $scope.digest()? Что вызывает удаление файла cookie? Если это из-за пределов angular, вам придется использовать $scope.$apply() для запуска часов. Если вы отлаживаете (Chrome/Firebug), поставьте точку останова в функции push() в angular-cookies.js (лучше всего использовать неминифицированную версию).   -  person asgoth    schedule 07.01.2013
comment
Я не делаю этого вне Angular, поэтому $scope.$apply() не нужен. Я не пробовал $cookieStore.removeKey(), но поскольку он просто выполняет delete $cookies[key];, разницы не будет.   -  person Joe Dyndale    schedule 07.01.2013
comment
Попробуйте проверить функцию push(). Эта функция должна быть вызвана для отправки изменений в cookie в браузер (по крайней мере, так это выглядит).   -  person asgoth    schedule 07.01.2013
comment
Пробовал. Также прошел через много кода. Похоже, массивы lastCookies и $browser.cookies обновляются корректно.   -  person Joe Dyndale    schedule 07.01.2013
comment
Была точно такая же проблема некоторое время назад. Кажется, что $.cookies может получить доступ только к файлам cookie, которые он установил сам. Мое решение заключалось в том, чтобы установить тот же путь к файлам cookie и очистить их с помощью файлов cookie jQuery вне углового приложения.   -  person Index    schedule 18.12.2013
comment
Мой сервер устанавливает токен cookie с путем =/. После удаления $cookies['token'] angularjs кажется, что файл cookie исчез, но в последующих запросах браузера я вижу, что файл cookie все еще отправляется. KG, не могли бы вы рассказать немного больше об обходном пути jQuery? Я попытался установить $document.cookie напрямую, чтобы принудительно истечь срок действия файла cookie ('токен' + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/'), но это, похоже, не имеет любой эффект.   -  person jamshid    schedule 17.06.2014


Ответы (3)


Я полагаю, вам следует проверить ответы с сервера - возможно, они включают поле заголовка «установить файл cookie», которое устанавливает значение файла cookie.

Вот пример Plunker, который иллюстрирует, как вы можете добавлять/изменять/удалять/отслеживать значение файла cookie (но без сервера сторонние ответы, которые могут изменить значения файлов cookie).

Но, как правило, объект $cookies является своего рода «прокси-объектом», который двусторонне отслеживается модулем AngularJS ngCookies и, с одной стороны, меняет свои поля при изменении файлов cookie браузера (так что вы можете $наблюдать за изменениями), но также изменения отражаются в настоящие файлы cookie браузера, поэтому вы можете изменить этот объект.

Таким образом, единственная причина, по которой файлы cookie не могут быть удалены, заключается в том, что вы удаляете их в браузере, а сервер снова устанавливает файл cookie, и после перезагрузки страницы он все еще существует.

person Valentyn Shybanov    schedule 07.01.2013
comment
Я проверил ответ сервера, и к нему не были прикреплены файлы cookie :( - person Joe Dyndale; 08.01.2013
comment
+1 за хорошее объяснение и хорошие примеры использования службы $cookie. Однако это не решило проблему для меня, поэтому я не могу отметить это как принятый ответ. Это моя вина, что вы не смогли ответить на вопрос, поскольку при написании вопроса была допущена серьезная ошибка (неправильный путь к приложению). Я обновил вопрос с правильным путем и объяснением того, в чем проблема оказалась. - person Joe Dyndale; 09.01.2013

Помните о домене файла cookie, который вы хотите удалить. Если вы работаете с несколькими поддоменами (например, один для статических ресурсов, другой для API), ваша проблема может заключаться в том, что вы пытаетесь удалить файл cookie для неправильного домена.

Просмотрите свои файлы cookie с помощью инструмента разработчика вашего браузера. Независимо от того, какой домен установлен для файла cookie, который вы хотите удалить, с которым у вас возникли проблемы, укажите его в параметре options для метода удаления.

$cookies.remove('JSESSIONID', {domain: 'domain.tld'});

СОВЕТ ПО БЕЗОПАСНОСТИ. Удаление идентификатора сеанса с помощью Javascript не приводит к удалению сеанса на сервере. Если ваши идентификаторы сеансов просочились, вы можете пострадать от фиксации сеанса. Было бы лучше удалить файл cookie, вызвав конечную точку выхода из вашего API, которая полностью очистит сеанс на сервере, чтобы его нельзя было использовать повторно.

person 2upmedia    schedule 26.10.2015
comment
Как и в случае с ОП, моя проблема была с путем, а не с доменом, но установка пути в параметрах наконец-то избавила меня от файла cookie. Это ответ, который указал мне правильное направление. - person Danny; 24.02.2016
comment
Я перепробовал много решений, но это единственное, которое дало мне удовлетворение: Установка пути И домена при удалении файла cookie: $cookies.remove(sessionId, {path: /, domain:mydomain.fr}); - person tchoum; 15.09.2016

Ответ, который вы дали в обновлении, кажется правильным: Angular $cookieStore может работать только с файлами cookie, значение пути которых совпадает с текущим путем.

Способ обмануть это — использовать решение, предоставленное ajspera для этой проблемы:

<head>
  <base href="/">
</head>

Просто добавьте <base href="/"> к элементу заголовка HTML, и в этот момент все заработает.

Альтернативное решение — указать путь к файлу cookie с помощью отправившего его сервера. В Node.js Express это выглядит так

res.cookie('specialCookie', 'special!', {path: '/myApp'});

Обратите внимание, что мне кажется, что $cookieStore удаляет завершающую косую черту, поэтому вам, возможно, придется попробовать оба способа.

person srlm    schedule 18.08.2014
comment
Спасибо, что действительно предоставили инструкции о том, как решить эту проблему. У меня работает базовый подход href, но я думаю, что может быть нежелательные последствия, поэтому я бы предпочел установить путь с сервера... но я не могу понять, откуда должно браться значение для /myApp. Я работаю на локальном хосте: 8080/mypage.html с аргументом angular.module 'theApp'. Но установка пути к '', /theApp или /theApp/ приводит к тому, что Angular не имеет доступа к файлу cookie. - person Dev93; 05.10.2014
comment
/myApp — это путь к отправляемому вами файлу cookie. В вашем случае вы должны использовать /mypage.html. В качестве альтернативы вы можете попробовать вариант без пути (по умолчанию путь к URL-адресу запроса) или, возможно, /mypage. - person srlm; 06.10.2014
comment
Но я хочу, чтобы куки были доступны для всех страниц моего сайта. Любой способ сделать это? В исходном вопросе автора у него есть site/myapp/app/index.html#topic, но в решении он ссылается только на myapp/app. - person Dev93; 06.10.2014