Правильный способ удаления файлов cookie на стороне сервера

Для моего процесса аутентификации я создаю уникальный токен, когда пользователь входит в систему и помещает его в файл 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.

Итак, какой лучший способ удалить cookie (желательно без JavaScript)? Метод set-the-expires-in-the-last кажется громоздким. А также почему это работает в FF, но не в IE или Safari?

Ответ 1

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

Отменить файл cookie, установив пустое значение и включить поле expires:

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

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

Ответ 2

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

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

Ответ 3

Почему бы не установить файл cookie maxAge < 0

// MaxAge=0 means no 'Max-Age' attribute specified.
// MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'
// MaxAge>0 means Max-Age attribute present and given in seconds
MaxAge   int

Ответ 4

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

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

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

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

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

    1. ...
    2. ...
    3. Обновите время создания вновь созданного cookie файла, чтобы оно соответствовало времени создания старого cookie файла.
    4. Удалите старый cookie из магазина cookie.
  2. Вставьте только что созданный файл 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 -date, определенный в [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 подобный этому, то:

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

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

Ответ 5

Для реализации JSX-RS для GlassFish Джерси я решил эту проблему по общему методу, описывая все общие параметры. По меньшей мере три параметра должны быть равны: 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();