Как обрабатывать несколько файлов 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 и хотите, чтобы ваше решение было надежным, лучше всего:
использовать другое имя файла cookie для переопределения в определенных путях, например:
- Set-cookie: a-global = 1; Path =/; Version = 1
- Set-cookie: a-example = 2; Path =/example; Version = 1
сохраните нужный путь в самом значении 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
Если вам нужно их отличить, вы должны дать им разные значения ключей.