Всем привет.
Этот топик — некая зарисовка на полях, которая, надеюсь, кому-нибудь пригодится, а кто-то — просто прочитает ее с интересом.
Не так давно мы запустили приложение для Твиттера по (не дай бог быть осужденным в пиаре) адресу
lu.ly
За несколько недель до релиза мы перевели приложение с внутреннего домена для разработки на production-домен как вдруг столкнулись с непонятной ситуацией.
В Internet Explorer и 6-й и 7-й и 8-й версии не устанавливались
некоторые cookie сайта.
Что происходит?
Точнее говоря — в Internet Explorer всех версий неожиданно перестала работать авторизация, вызываемая из библиотеки для Facebook-а.
Что самое странное — сама авторизация происходила и методы возвращали успешный результат.
Но уже на следующей странице — мы не получали никаких данных о том, что пользователь сайта как-то связан с Facebook-аккаунтом.
Сперва, нам и в голову не могло прийти что проблемы находятся на стороне сервера или клиентской части. Несколько часов конфигурирования Facebook-приложения ни к чему не привели.
И в чем дело?
После безуспешных попыток разобраться с Facebook-приложением мы перешли к серверной части, ожидая что проблема в нашем использовании Facebook-библиотеки. На площадке для разработки мы создали простое приложение в котором стали отслеживать — как именно Facebook сохраняет данные об авторизации для данного сайта.
Механизм работы заключался в следующем — как только библиотека Facebook-а на сайте получала ответ об успешной авторизации — пользователю устанавливался ряд cookies, обыкновенных доменных cookies.
И вот вывод отладочной информации и показал нам что cookies не ставятся.
Самым странным было то, что ряд кук все таки был установлен — работали сессии, работала авторизация на твиттере, и только Facebook-куки не до ходили до клиента.
Еще раз подчеркну — куки, выставляемые библиотекой Facebook-а были не кросдоменные, они выставлялись не на Facebook-сервере а на нашей машине для наших клиентов. И они пропадали.
И в чем причина?
Еще раз — в Фаирфоксе, Опере (и как я подозреваю, но не проверял — в Сафари и Хроме) все было хорошо. Куки не устанавливались только в всеми любимом Internet Explorer.
Дальше начались несколько часов затяжных боев. Мы проверили все — P3P заголовки, изрыли вдоль и поперек библиотеку Facebook-а и в итоге решили препарировать ее по кусочкам. Через 4 часа экспериментов от библиотеки остался только фрагмент устанавливающий куки. И он все равно не работал.
Ручная установка Expire-даты не помогала. Смена имени кук не помогала. В конце концов мы подумали — может быть проблема в веб-сервере? И перенесли все на другой сервер и на другой домен, где, о чудо, куки незамедлительно установились.
Теперь к сути. Еще раз напомню что домен — двухбуквенный.
Не знаю чем мы руководствовались но кто-то, больше из интереса, написал в гугле — «IE two letter domain»
Когда мы увидели результаты удивлению не было предела.
support.microsoft.com/kb/310676
Internet Explorer does not set a cookie for two-letter domains
Вот именно так. Для кук с явным указанием двухбуквенного доменного имени. Не ставит, и все.
Почему? А потому что куки нельзя ставить на Top Level Domains такие как .com, .net, .ru и… и домены подобные co.uk.
Но ведь никто особенно не знает какой домен еще может оказаться TLD в длительной перспективе. Разные браузеры с этим справляются по разному, нашел свой путь и Internet Explorer.
Если не сказано иначе любой двухбуквенный домен IE считает TLD-доменом и не ставит доменные куки на него
Но ведь должен же быть фикс?
Да фикс есть, Microsoft обещала это в своей статье и выпустила его.
Теперь конечный пользователь, если он все-таки хочет выставить куку на двухбуквенный домен волен это сделать.
Для этого всего-лишь надо установить специальный ключ в реестре как то рекомендует MS:
# Start Registry Editor
# Locate and then click the following registry subkey:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\5.0
# On the Edit menu, click Add Value, and then add the following registry entry:
Name: SpecialDomains
Type: REG_SZ
Value: lp. rg. ac.
Что делать веб-разработчикам?
Есть два ответа на этот вопрос.
Один скорее смешной, и его, опять же, рекомендует Microsoft:
To work around this problem, do not use a domain name with less than three letters. You may also want to use HTTP redirects that route requests for www.xx.xx to www.xxx.xx.
Другой — не менее топорный — не использовать доменных кук.
В ситуации с Facebook-библиотекой все решилось снятием домена с установки cookie после авторизации.
Что делать — в случае если доменные куки все-таки нужны? Вопрос остается открытым.
Надеюсь, что эта информация кому-то оказалась полезной, спасибо за внимание! :)
Update:
как верно подмечено информация об этом уже появлялась на хабре вот в этом посте —
djru.habrahabr.ru/blog/57463/
так же полезную информацию вы можете встретить
1. здесь —
crisp.tweakblogs.net/blog/ie-and-2-letter-domain-names.html
где среди прочего отмечается что многие браузеры решают проблему определения TLD по своему.
Опера, для примера, при установке куки на двухбуквенный домен делает dns lookup по этому домену для проверки на его существование. Остается однако риск того что регистратор может сделать двухбуквенный домен доступным для резолвинга.
2. и здесь
drupal.org/node/280623
где в качестве решения предлагается добавлять www к домену, что однако ограничивает пользователей, обращающихся к домену без www (а прелесть двухбуквенного домена во много связана именно с его коротким названием)
Update 2:
В процессе обсуждения выяснились подробности касательно поведения Firefox для TLD, а конкретно для географических доменов.
Очевидно, что список TLD-доменов жестко зашит в библиотеки фаирфокса, и среди прочего, в этом списке указаны географические домены.
Таким образом, доменные куки в Firefox на географические домены (такие как chel.ru — для Челябинска, tyumen.ru для Тюмени) ставится не будут.
Спасибо
nickyx3.habrahabr.ru/ за наводку!
комментарии (47)
все же надеюсь что пост может оказаться полезным тем кто недавно читает хабр или, если вдруг кто-то пропустил тот пост (как случилось со мной, к сожалнию)
еще раз искренне извиняюсь!
если еще несколько замечаний будет — уведу пост себе в блог, просто чтобы не забыть
это действительно незабываемо ;)
IE ПРИНИМАЕТ!!! куки на двухбуквенный домен и вот вам пример: 74.ru/cook_test.php
вот пример того же самого файла (залинкован) на другом домене: chel.ru/cook_test.php
вот сырцы: 74.ru/cook_test.phps
«Фишка» в том, что он не принимает куки только в том случае если в заголовке Set-cookie приходит принудительно домен по стандарту RFC 2109.
PS: Для себя пришли к выводу, что стоит отказаться от доменов www. и авторизовываться без явного указания домена.
к сожалению в отношении некоторых вещей проблема сохраняется и очень серьезная — google analytics не фиксирует ie пользователей как таковых вообще
сейчас написали им вопрос, они сообщили что передали проблему техническому персоналу, но как быстро мы получим ответ — это конечно вопрос, извиняюсь за каламбур
думаю что мозг бы он нам уже давно выел, если бы что-то не работало :)
ряд довольно серьезных вещей в knowledge base микрософта объяснялись фразой, которая вполне могла бы стать девизом — this behavior is by design.
чтобы было тогда я уже не вспомню, но стокнувшись с проблемой о которой я написал в посте я немного погуглил и освежил память на тему «by design».
support.microsoft.com/kb/915850
You may experience a 45-second delay when you run a full-text query in an instance of SQL Server 2005 that is running on a server without Internet access
status: This behavior is by design.
support.microsoft.com/kb/971613/
You cannot install the Microsoft Compressed (LZH) Folder add-in in Windows 7
status: This behavior is by design.
support.microsoft.com/kb/262981
Internet Explorer Uses Proxy Server for Local IP Address Even if the «Bypass Proxy Server for Local Addresses» Option Is Turned On
status: This behavior is by design.
и многое другое :)
нет, я ничуть не собираюсь ругать Microsoft как компанию, понимая что разработка любого крупного продукта связана с огромным количеством подводных камней, но некоторые моменты, если их собрать вместе — выглядят очень интересно :)
я хотел было сделать что-то типа странички куда бы можно было собрать все баги с подобным статусом, но меня уже обогнали ;) — bhandler.spaces.live.com/Blog/cns!70F64BC910C9F7F3!6695.entry
запрет на установку кук на TLD это прежде всего защита от баннеро-подобных служб когда среди кук могут быть личные данные и их могут специально ставить для того чтобы сеть сайтов получила доступ к этим данным и каким-то образом таргетировала выдачу.
остается открытым вопрос — зачем тогда ограничиваются только TLD когда есть еще миллион других способов эти данные передать, и яндекс директ, формируемый по поисковым запросам пользователя тому пример
Кстати, я правильно понял, что на двухСИМВОЛьные домены это не распространяется (с цифрами)? То есть на a1.ku, допустим?
судя по этому комментарию, к сожалению — распространяется :(
v1.ru/cook_test.php
Может покопать в сторону .htaccess реврайтов? Например при заходе с эксплорера на lu.ly редиректить на сабдомен ie.lu.ly (допустим), чья папка является симлинкой на основной домен(ну или алиасом на него же). А хтаксесом уже подставлять «френдли урл» в виде lu.ly Точно не скажу сработает или нет — не сталкивался с такой проблемой и потестить негде, но Вы можете попробовать.
Кстати он не отказался бы от инвайта
Этот код является видимо каким-то магическим танцем с бубном, чтобы в setcookie не передавался домен :)
Drupal, блин :)))
есть как минимум 2 географических домена в наличии и никаких проблем там не испытываем с авторизацией.
я вот пример приводил: chel.ru/cook_test.php — географический домен (все работает)
Без домена ставятся, но задача то не в том чтоб их поставить, а в том чтоб поставить именно .geodomain.ru, чтоб оно работало еще и на всех доменах some.geodomain.ru.
А с tyumen.ru мы «повеселились» прилично. Мозг был взорван. Потом нашли что все гео домены в FF забиты в DLL хардкодед.
Более того, в RFC валяется draft предложение о добавлении ip-based dns lookup cookie для этих доменов, чтоб браузер лукапил в dns ip адреса доменов типа
.some-geo-or-public.domain
some-sub.some-geo-or-public.domain
и т.п. при этом ставя куку для домена второго уровня, но отдавая ее только тем субдоменам, которые резолвятся в тот же ip адрес. И кажется opera уже это сделала.
если предположить, что бразуер просто делает gethostbyname, то это по меньшей мере неполное решение проблемы, хотя бы потому что у вас может резолвиться домен в несколько адресов, например:
Например:
мы пришли на chel.ru, с адресом 1.2.3.4, получили куку .chel.ru, броузер запомнил что она получена c 1.2.3.4, при переходе на second.chel.ru, подвешеному на 1.2.3.4, сервер куку у пользователя получит, а вот при переходе на third.chel.ru с адресом 1.2.3.5, кука не отдастся по соображениям безопасности. Все это относится только к доменам являющимся GEO, PUBLIC и т.п.
сделайте nslookup для доменов ya.ru, first.ya.ru, second.ya.ru
там у всех доменов IP одинаковые (но не один, а несколько)
nslookup для доменов chel.ru, first.chel.ru, second.chel.ru может быть тот же самый — это балансировка. от нее сложно отказаться.
Теперь понятно почему часто двухбуквенные домены перенаправляют на домены с www (например nn.ru).
ставим куки на домен .xx.xx
кука в итоге доступна на всех поддоменах.
Раньше во внутрикорпоративных сетях было нередким делом давать Windows-домену полное имя, не разделенное точками, т.е. по сути делать домен первого уровня. Допустим, домен с именем abc (это именно FQDN-имя домена, т.е. полное). Сейчас, конечно, такого нико не делает, но у нас в организации есть такой старенький домен.
И в Windows, как правило, нет проблем из-за такого домена первого уровня. Но вот если в IE добавить в список Trusted Sites какой-то конкретный сервер из этого домена (например, сервер с FQDN-именем servername.abc), то IE не понимает, что это имя одного сервера, он уверен в том, что сервер не может быть в домене первого уровня, поэтому считает, что ему указали не имя конкретного сервера, а домен второго уровня, и дополняет это имя лидирующей звёздочкой с точкой: *.servername.abc, хотя его об этом никто не просил. В результате вместо отдельного имени сервера в список добавляется совсем ненужное пространство адресов.