HttpWebRequest cookie с пустым доменом - PullRequest
18 голосов
/ 16 декабря 2010

У меня есть действие ASP.NET MVC, которое отправляет запрос GET на другой сервер через HttpWebRequest. Я хочу включить все файлы cookie в запрос исходного действия в новый запрос. Некоторые из файлов System.Web.HttpCookies в исходном запросе имеют пустые доменные значения (т.е. ""), что, очевидно, не вызывает никаких проблем. Когда я создаю System.Net.Cookie, используя имя, значение, путь и домен каждого из этих файлов cookie, и добавляю его в CookieContainer запроса, я получаю эту ошибку:

"System.ArgumentException: параметр '{0}' не может быть пустой строкой. Имя параметра: cookie.Domain"

Вот некоторый код, который выдаст ту же ошибку (при добавлении куки):

var request = (HttpWebRequest)WebRequest.Create("http://www.whatever.com");
request.Method = "GET";
request.CookieContainer = new CookieContainer();
request.CookieContainer.Add ( new Cookie ( "MyCookieName", "MyCookieValue", "/", "") );

EDIT

I сортировка исправила это, используя «localhost» для домена вместо нулевого или пустого строкового значения из исходного HttpCookie. Итак, почему пустой домен не работает для CookieContainer? И использует ли HttpCookie пустое значение для обозначения localhost или мне нужно найти другое решение этой проблемы?

Ответы [ 4 ]

8 голосов
/ 14 октября 2012

Отказ от ответственности:

Как было сказано ранее @feroze, установка домена cookie на localhost не будет работать для вас так хорошо. Я предполагаю, что вы пишете помощника, который позволяет вам туннелировать HTTP-запросы на чужие домены. Обратите внимание, что это не лучшая практика и во многих случаях не требуется (т. Е. jQuery имеет много классной междоменной поддержки, встроенной , также см. Новую спецификацию CORS ). Но иногда вы можете застрять в этом (т. Е. Внешним ресурсом является только XML и он находится на сервере, который не поддерживает CORS).

Справочная информация о доменах cookie и о том, как они работают:

Если вы еще не взглянули на HTTP Cookie: домен и путь в Википедии - там есть почти все, что вам нужно знать.

При оценке файла cookie домен и путь учитываются и клиентом («локальный» запросчик) и веб-сервером («сторонний» ответчик) , Когда клиент запрашивает ресурс, клиент должен отправлять файлы cookie только в тех случаях, когда эти файлы cookie соответствуют домену (или более общему родительскому домену ) и пути (или более общему родительскому пути) из запрашиваемый URI.

Веб-браузеры обрабатывают это правильно. Если в веб-браузере есть файл cookie для домена «localhost», и вы запрашиваете, например, «google.com», эти файлы cookie для домена «localhost» не будут отправлены в запросе на «google.com». - Фактически, большинство современных браузеров не просто не отправляют их, они полностью игнорируют их в заголовках ответов Set-Cookie, которые они получают (они называются сторонними cookie-файлами - что позволяет принимать сторонние cookie-файлы в вашем веб-браузер - серьезная проблема конфиденциальности / безопасности - не делайте этого!).

Он работает и в другом направлении - даже если клиент вряд ли включит сторонний cookie в запрос, если он это сделает, иностранный веб-сервер должен его игнорировать (и даже некоторые cookie для правильного домены / пути, чтобы предотвратить печально известную проблему super-cookie . (т. е. веб-сервер, на котором размещен "example.com", должен игнорировать файлы cookie, принадлежащие его родительскому домену: ".com", потому что ".com "это" публичный суффикс ")).

Что делать [если нужно]:

Действия, которые я рекомендую для вас, - это когда вы читаете в куки вашего клиента (я не парень MVC, но в обычном ASP.NET это было бы в Request.Cookies), просматривайте их (убедитесь, что чтобы отфильтровать законные куки-файлы вашего собственного сайта, особенно SessionId и т. д. - или правильно использовать Path, чтобы они никогда не отправлялись на эту страницу в первую очередь), а затем добавлять их по одному в коллекцию cookie исходящего запроса, переписывая домен быть "www.whwhat.com" (в вашем примере - если вы делаете это динамически, загрузите URL-адрес в новый объект Uri () и используйте свойство .Host), а затем установите для пути значение "/" , - Это создаст заголовок «Cookie» для исходящего запроса на сторонний веб-сервер.

Когда этот запрос возвращается на ваш сервер, вам необходимо проверить его входящий ответ на наличие новых файлов cookie - эти файлы cookie могут быть переупакованы и отправлены обратно вашему клиенту в цикле, аналогично тому, который я иллюстрировал в предыдущем параграфе. за исключением того, что вы захотите переписать Host, чтобы он был Request.Url.Host - и вы захотите установить путь обратно на "/", если путь к вашей промежуточной странице не является статическим (я предполагаю, что это не так вы используете MVC), то вы хотите установить его, например, в Request.Url.AbsolutePath.

Счастливого кодирования!

EDIT: Кроме того, вы захотите установить тег X-Forwarded-For исходящего запроса, чтобы вызываемый вами веб-сайт не думал, что ваш веб-сервер - это единственный клиент, который рассылает спам. из них.

3 голосов
/ 29 мая 2013

Некоторый фон

Это происходит потому, что CookieContainer является клиентским контейнером, предназначенным для повторного использования в нескольких запросах HttpWebRequest. Повторное его использование обеспечивает ожидаемое поведение файлов cookie, при котором файлы cookie, установленные удаленным хостом, отправляются обратно при каждом последующем запросе HttpWebRequests, направленном на тот же хост.

В результате повторного использования CookieContainer может фактически содержать cookie-файлы от нескольких запросов и \ или хостов.

Итак, чтобы определить, какие из файлов cookie в контейнере необходимо отправить с определенным HttpWebRequest на какой-либо хост (домен), CookieContainer проверяет свойство Domain и Path.

Именно поэтому Cookie в CookieContainer должен иметь действительный домен.

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


В частности, в вашем случае при копировании файлов cookie из CookieCollection в CookieContainer вам необходимо установить свойство Domain каждого файла cookie для домена, на который вы собираетесь перенаправлять запрос, чтобы HttpWebRequest узнал, что файлы cookie будут отправив запрос.

2 голосов
/ 24 августа 2016

Не уверен, что это решит вашу проблему.Но чтобы добавить файлы cookie без свойства «Домен», необходимо добавить в заголовки файлы cookie, используя HttpRequestHeader.Cookie следующим образом.

request.Headers.Add(HttpRequestHeader.Cookie, "Your cookies...");

Надеюсь, это поможет!

0 голосов
/ 23 февраля 2011

Вы пытаетесь отправить куки на localhost, верно?

Почему бы вам не сделать что-то подобное, если вы дадите собственному компьютеру настоящее имя:

  1. Правитьфайл вашего хоста и добавьте строку «127.0.0.1 myname.com»
  2. Тест с использованием myname.com - который фактически является вашим локальным хостом.

Ваш браузер или приложение не будут знатьРазница и отправьте куки на myname.com, если это место, где куки принадлежат.

Подробная информация:

  1. Файл Hosts в Windows расположен по адресу C: \ Windows \System32 \ drivers \ etc \ hosts
...