Как обрабатывать несколько файлов cookie с тем же именем?

Скажем, например, у меня было приложение, отправляющее следующие HTTP-заголовки для установки в cookie с именем "a":

Set-Cookie: a=1;Path=/;Version=1
Set-Cookie: a=2;Path=/example;Version=1

Если я получаю доступ к /example на сервере, оба пути действительны, поэтому у меня есть два файла cookie с именем "a"! Поскольку браузер не передает информацию о пути, эти два файла cookie нельзя отличить.

Cookie: a=2; a=1

Как следует обрабатывать этот случай? Выберите первый? Создайте список со всеми значениями cookie? Или должен ли такой случай рассматриваться как ошибка разработчика?

Ответ 1

Из в этой статье о SitePoint:

Если несколько файлов cookie одинакового имени соответствуют заданному URI запроса, один выбирается браузером.

Чем более конкретный путь, тем выше приоритет. Однако приоритет, основанный на других атрибутах, включая домен, не указан и может варьироваться между браузерами. Это означает, что если вы установили файлы cookie с тем же именем ".example.org" и "www.example.org", вы не можете быть уверены, какой из них будет отправлен назад.

Изменить: эта информация из 2010 выглядит устаревшей, кажется, что браузеры теперь могут отправлять несколько файлов cookie в ответ, см. ответ @Nate ниже для деталей.

Ответ 2

Ответ со ссылкой на статью в SitePoint не является полностью полным. См. RFC 6265 (если честно, этот RFC был выпущен в 2011 году после публикации этого вопроса, который заменяет собой предыдущие RFC 2965 от 2000 года и RFC 2109 от 1997).

В разделе 5.4, подразделе 2 сказано следующее:

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

  • Файлы cookie с более длинными путями перечислены перед файлами cookie с более короткими путями.

ПРИМЕЧАНИЕ. Не все пользовательские агенты сортируют список файлов cookie в этом порядке, но это порядок отражает обычную практику, когда этот документ был написан, и, исторически существовали серверы, которые (ошибочно) зависели от этот заказ.

В разделе 4.2.2 также есть этот маленький драгоценный камень:

... серверы НЕ ДОЛЖНЫ полагаться на порядок сериализации. В в частности, если заголовок Cookie содержит два файла cookie с одинаковыми имя (например, которые были установлены с различными атрибутами пути или домена), серверы НЕ ДОЛЖНЫ полагаться на порядок, в котором эти файлы cookie появляются в заголовке.

В вашем примере запроса cookie (Cookie: a = 2; a = 1) обратите внимание, что cookie, установленный с путем /example (a = 2), имеет более длинный путь, чем файл с путем /(a = 1), и поэтому он отправляется обратно вам первым в очереди, что соответствует рекомендации спецификации. Таким образом, вы более или менее правы в своем предположении, что вы можете выбрать первое значение.

К сожалению, язык, используемый в RFC, чрезвычайно специфичен - использование слов НЕ ДОЛЖНО и НЕ СЛЕДУЕТ вводить двусмысленность в RFC. Они указывают на соглашения, которые должны соблюдаться, но не обязательно должны соответствовать спецификации. Хотя я достаточно хорошо понимаю RFC, я не провел исследования, чтобы увидеть, что делают клиенты в реальном мире; Возможно, что один или несколько браузеров или других программ, действующих в качестве клиентов HTTP, могут не отправлять файл cookie с самым длинным путем (например,/пример) первым в заголовке Cookie:

.Если вы можете контролировать значение файла cookie и хотите, чтобы ваше решение было надежным, лучше всего:

  1. использовать другое имя файла cookie для переопределения в определенных путях, например:

    • Set-cookie: a-global = 1; Path =/; Version = 1
    • Set-cookie: a-example = 2; Path =/example; Version = 1
  2. сохраните нужный путь в самом значении cookie:

    • Set-cookie: a = 1 & path =/; Path =/; Version = 1
    • Набор cookie: a = 2 & путь =/пример; путь =/пример; версия = 1

Оба эти обходных пути требуют дополнительной логики на сервере, чтобы выбрать желаемое значение файла cookie, сравнивая запрошенный URL-адрес со списком доступных файлов cookie. Это не слишком красиво. К сожалению, у RFC не было предвидения требовать, чтобы более длинный путь полностью заменял cookie файл с более коротким путем (например: в вашем примере вы получите Cookie: a = 2 only).

Ответ 3

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

Я настоятельно рекомендую избегать этой практики.

Однако, если вы действительно хотите знать, как браузеры (и приложения) обрабатывают этот сценарий, почему бы не построить тестовую установку и не попробовать.

Ответ 4

Нет ничего плохого в том, что у вас есть несколько значений для одного и того же имени... если вы хотите их. Вы даже можете включить дополнительный контекст в значение.

Если вы этого не сделаете, то, конечно, разные имена являются решением, если вы хотите оба контекста.

Альтернативой является отправка одного и того же имени cookie с тем же путем (и доменом) даже из более конкретных путей. Эти установленные команды cookie будут перезаписывать значение этого файла cookie.

Теперь, когда вы знаете самую важную часть (как они работают), и что вы можете выполнить то, что вам нужно несколькими способами, мой ответ на ваш вопрос: это проблема разработчика.

Ответ 5

Если вам нужно их отличить, вы должны дать им разные значения ключей.