Проблема с настройкой Cookie w/ PHP

Я работаю локально через два "домена". У меня есть виртуальные хосты enterprise.local и application.local на моей машине, и мне нужно установить cookie домена для "local" или ".local". Однако у меня возникают некоторые проблемы с правильной установкой cookie. В application.local у меня есть это:

setcookie( 'iPlanetDirectoryPro', trim( $token_id ), '0', '/', '.local' );
header( 'Location: /adcom-sso' );

Я также попробовал это:

header( 'Set-Cookie: iPlanetDirectoryPro=' . trim( $token_id ) . '; path=/' );
header( 'Location: /adcom-sso' );

С помощью setcookie(), cookie никогда не устанавливается. С использованием Set-Cookie заголовок, cookie установлен. Я удалил перенаправление с обоих, и результат никогда не меняется. Это работает для Set-Cookie, но не для setcookie(), Это было бы хорошо, так как у меня нет предпочтения, какое решение я использую, но в Set-Cookie Решение, как только я добавляю домен, все это ломается:

header( 'Set-Cookie: iPlanetDirectoryPro=' . trim( $token_id ) . '; path=/; domain=local' );

Как только я добавляю значение домена, я получаю ошибку заголовка:

Header may not contain more than a single header, new line detected.

Я пробовал значение домена как "local" и ".local". Поведение не меняется.

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

ОБНОВЛЕНИЕ: я думаю, что сузил это немного дальше. Кажется, что оба способа будут работать, пока я не включаю значение домена. Может ли быть проблема с использованием "local" или ".local" в качестве конкретного домена для cookie?

1 ответ

Решение

РЕДАКТИРОВАТЬ: Я теперь взглянул на RFC2109, 4.3.2 Отказ от Cookies:

  • Значение атрибута Domain не содержит встроенных точек или не начинается с точки.

    ...

  • Set-Cookie с Domain=.com или Domain=.com., Всегда будет отклонен, потому что нет встроенной точки.

Похоже, что браузер отклоняет ".local" из-за проблем безопасности. Чтобы установить cookie для домена, он должен иметь как минимум две точки (например, ".cookiedomain.local").

Установка cookie из одного субдомена (например, one.local) для другого субдомена (например, another.local) невозможна AFAIK. Чтобы решить эту проблему, вы можете перенаправить пользователя в домен cookie, который устанавливает / получает все файлы cookie и снова перенаправляет пользователя туда, откуда он пришел, с данными cookie, включенными в URL в качестве параметров запроса. Microsoft делает (или делала) это так для своих собственных доменов (msn.com, microsoft.com).


Полученная ошибка ("Заголовок может не содержать...") срабатывает только в том случае, если строка, которую вы передаете в качестве аргумента header() содержит символ перевода строки, за которым не следует ни пробел, ни табуляция (который будет продолжать заголовок на следующей строке).

Сейчас, setcookie() будет на самом деле urlencode() его значение (setrawcookie() не будет), поэтому перевод строки не вызовет там ошибку.

trim() Функция, с другой стороны, удалит пробелы только с начала и конца аргумента и оставит все другие символы перевода строки без изменений. Так что, возможно, вы могли бы попробовать что-то вроде preg_replace('/\s+/', '') вместо.

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

Тем не менее, это не объясняет, почему ваш первый header() кажется, работает (с переводами строки в нем); Кажется, что некоторые из ваших значений cookie имеют перевод строки, а некоторые - нет.

Кстати, установка домена в положение ".local" (ведущий ".") - правильная вещь, если вы хотите, чтобы поддомены видели cookie.

Некоторые дополнительные предостережения о настройке куки с setcookie() обсуждаются в документации PHP (особенно комментарии пользователей).

Другие вопросы по тегам