Правильный способ удаления куки на стороне сервера - PullRequest
113 голосов
/ 13 марта 2011

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

Итак, я бы отправил что-то подобное с сервера:

Set-Cookie: token=$2a$12$T94df7ArHkpkX7RGYndcq.fKU.oRlkVLOkCBNrMilaSWnTcWtCfJC; path=/;

, который работает во всех браузерах. Затем, чтобы удалить cookie, я отправляю аналогичный cookie с полем expires, установленным на 1 января 1970

Set-Cookie: token=$2a$12$T94df7ArHkpkX7RGYndcq.fKU.oRlkVLOkCBNrMilaSWnTcWtCfJC; path=/; expires=Thu, Jan 01 1970 00:00:00 UTC; 

И это прекрасно работает в Firefox, но не удаляет cookie в IE или Safari.

Так, каков наилучший способ удалить куки (желательно без JavaScript)? Метод «установить истекает в прошлом» кажется громоздким. А также почему это работает в FF, а не в IE или Safari?

Ответы [ 4 ]

186 голосов
/ 13 марта 2011

Отправка того же значения файла cookie с добавлением ; expires не приведет к его уничтожению.

Признать недействительным cookie, установив пустое значение, а также включить поле expires:

Set-Cookie: token=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT

Обратите внимание, что вы не можете заставить все браузеры удалять куки.Клиент может настроить браузер таким образом, чтобы файл cookie сохранялся, даже если срок его действия истек.Установка значения, как описано выше, решит эту проблему.

12 голосов
/ 17 декабря 2012

Установка «истекает» на прошлую дату является стандартным способом удаления куки.

Возможно, ваша проблема в том, что формат даты не является стандартным. IE, вероятно, ожидает только GMT.

9 голосов
/ 01 декабря 2018

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

Использование атрибута Expires в прошлом для удаления файла cookie является правильным и является способом удаления файлов cookie, продиктованных спецификацией. В разделе примеров RFC 6255 указано:

Наконец, чтобы удалить куки, сервер возвращает заголовок Set-Cookie с датой истечения в прошлом. Сервер будет успешным при удалении cookie, только если атрибут Path и Domain в заголовок Set-Cookie соответствует значениям, использованным при создано.

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

  1. Если [при получении нового файла cookie] хранилище файлов cookie содержит файл cookie с тем же именем, доменом и путем, что и вновь созданный файл cookie:

    1. ...
    2. ...
    3. Обновите время создания вновь созданного файла cookie, чтобы оно соответствовало времени создания старого файла cookie.
    4. Удалите старую куки из магазина печенья.
  2. Вставьте только что созданный файл cookie в хранилище.

Срок действия файла cookie истек, если срок действия файла cookie истек в прошлом.

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

Пункты 11-3, 11-4 и 12 выше вместе означают, что при получении нового файла cookie с тем же именем, доменом и путем старый файл cookie должен быть удален и заменен новым файлом cookie. Наконец, пункт ниже о просроченных cookie-файлах дополнительно диктует, что после этого новый cookie-файл должен также быть немедленно удален. На данный момент в спецификации нет места для маневра для браузеров; если бы браузер предлагал пользователю возможность отключить истечение срока действия cookie, как это принято в некоторых браузерах, то это было бы нарушением спецификации. (Такая функция также будет мало полезна, и, насколько мне известно, ее нет ни в одном браузере.)

Почему тогда ОП этого вопроса заметил, что этот подход потерпел неудачу? Хотя я не вычистил копию Internet Explorer, чтобы проверить его поведение, я подозреваю, что это произошло потому, что значение OP Expires было искажено! Они использовали это значение:

expires=Thu, Jan 01 1970 00:00:00 UTC;

Однако это синтаксически неверно двумя способами.

Синтаксическая секция спецификации определяет, что значение атрибута Expires должно быть

rfc1123 -дата, определенная в [RFC2616], раздел 3.3.1

Следуя второй ссылке выше, мы находим это в качестве примера формата:

Sun, 06 Nov 1994 08:49:37 GMT

и найдите, что определение синтаксиса ...

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

    В частности, он определяет rfc1123-date следующим образом:

    rfc1123-date = wkday "," SP date1 SP time SP "GMT"
    

    и определяет date1 следующим образом:

    date1        = 2DIGIT SP month SP 4DIGIT
                 ; day month year (e.g., 02 Jun 1982)
    

и

  1. не разрешает UTC в качестве часового пояса.

    В спецификации содержится следующее утверждение о том, какие смещения часового пояса допустимы в этом формате:

    Все HTTP-метки даты / времени ДОЛЖНЫ быть представлены в среднем времени по Гринвичу (GMT) без исключения.

    Более того, если мы углубимся в исходную спецификацию этого формата даты и времени, мы обнаружим, что в его начальной спецификации в https://tools.ietf.org/html/rfc822, в разделе Синтаксис перечислены «UT» (что означает «универсальное время»).") в качестве возможного значения, но не перечисляет не UTC (Всемирное координированное время) как действительное.Насколько я знаю, использование «UTC» в этом формате даты никогда не было допустимым;это было недопустимое значение, когда формат был впервые указан в 1982 году, а спецификация HTTP приняла строго более ограничительную версию формата, запретив использование всех значений «зоны», кроме «GMT»".

Если бы задающий вопрос здесь использовал вместо этого атрибут Expires, такой как this , тогда:

expires=Thu, 01 Jan 1970 00:00:00 GMT;

, тогдапредположительно сработало.

0 голосов
/ 28 июня 2018

Для реализации GlassFish Jersey JAX-RS я решил эту проблему с помощью общего метода, описывающего все общие параметры.Как минимум три параметра должны быть равны: name (= "name"), path (= "/") и domain (= null):

public static NewCookie createDomainCookie(String value, int maxAgeInMinutes) {
    ZonedDateTime time = ZonedDateTime.now().plusMinutes(maxAgeInMinutes);
    Date expiry = time.toInstant().toEpochMilli();
    NewCookie newCookie = new NewCookie("name", value, "/", null, Cookie.DEFAULT_VERSION,null, maxAgeInMinutes*60, expiry, false, false);
    return newCookie;
}

И использовать его обычным способом для установки cookie:

NewCookie domainNewCookie = RsCookieHelper.createDomainCookie(token, 60);
Response res = Response.status(Response.Status.OK).cookie(domainNewCookie).build();

и удалить cookie:

NewCookie domainNewCookie = RsCookieHelper.createDomainCookie("", 0);
Response res = Response.status(Response.Status.OK).cookie(domainNewCookie).build();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...