Чтение и запись cookie

132

Протокол HTTP не поддерживает состояние, поэтому в принципе HTTP-серверы отвечают на каждый запрос клиента, не привязывая его к предыдущим или последующим запросам. Для поддержания состояния между клиентом и сервером нужно программно отслеживать сеанс пользователя, фиксируя информацию о том, к каким ресурсам обращается пользователь и какие данные он вводит. Отслеживание сеанса позволяет поддерживать связь между двумя последовательными запросами, выполненными к какому-либо серверу в Интернете.

Существуют разнообразные способы поддержания состояния в течение сеанса, например, cookie, которые являются наиболее распространенными средствами поддержания состояния приложения.

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

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

Для управления cookie используем класс CookieCollection из пространства имен System.Net. Этот класс обеспечивает механизм обработки нескольких cookie.

Запись cookie на клиенте

Для демонстрации использования cookie в .NET построим пример приложения, который будет создавать cookie, а затем создадим тестовую страницу ASP.NET, чтобы проверить, был ли создан cookie.

Следующий код с помощью объекта Cookie устанавливает cookie MyName со значением "Alex" и отправляет его серверу в HTTP-запросе. Заметьте, что объект Cookie является лишь представлением cookie в памяти — он не сохраняет никаких данных на диске клиента. Когда создаем cookie, мы также устанавливаем путь (URI на сервере, которому этот cookie будет отправляться) и имя домена, для которого cookie действителен.

Получив объект Cookie, можно установить его свойство Expires, чтобы указать, когда истечет отведенное для него время (и мы перестанем отправлять его на сервер). Установив эти свойства, добавляем cookie в CookieContainer запроса. CookieContainer — это коллекция cookie, которая позволяет хранить cookie для нескольких сайтов. Каждый cookie, добавленный в CookieContainer, включается во внутреннюю коллекцию всех cookie, связанных с конкретным URL:

// Создание cookie
Cookie cookie = new Cookie("MyName", "Alex", "/", "localhost");
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(
       "http://localhost:47747/CookieTest.aspx");
request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(cookie);

HttpWebResponse responce = (HttpWebResponse)request.GetResponse();

using (StreamReader stream = new StreamReader(
        responce.GetResponseStream(), Encoding.UTF8))
{
        txb_text.Text = stream.ReadToEnd();
}

Для тестирования кода создадим очень простую страницу ASP.NET с именем CookiesTest.aspx. Эта страница просто получает значение cookie. Это значение записывается в поток ответа:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CookieTest.aspx.cs" %>

<%
   HttpCookie cookie = Request.Cookies["MyName"];

   if (cookie != null)
       Response.Write("Значение cookie получено - " + cookie.Value);
   else
       Response.Write("Значение cookie не получено");
 %>

Теперь компилируем и выполняем код. Эта программа выполняет запрос к CookiesTest.aspx и отображает ответ в текстовом элементе WPF. Ниже показан вывод содержания страницы при выполнении программы. Как можно видеть, значение cookie MyName было получено страницей ASP.NET:

Передача cookie серверу

Считывание cookie на клиенте

Используя пространство имен System.Net среды .NET Framework, считать cookie так же просто, как записать. Чтобы в этом убедиться, опять используем очень простую страницу ASP.NET, которая называется WriteCookie.aspx. Эта страница лишь создает новую запись cookie и отправляет клиенту:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WriteCookie.aspx.cs" %>

<% 
    string UserName = "Alexandr Erohin";

    HttpCookie cookie = new HttpCookie("username", UserName);
    Response.Cookies.Add(cookie);
    Response.Write("Hello, " + UserName);
 %>

Запросив эту страницу из клиента, можем обратиться к записи cookie с именем username через свойство Cookies класса HttpWebResponse:

string query = "http://localhost:47747/WriteCookie.aspx";
            
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(query);
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

txb_text.Text = "Cookie username = " + resp.Cookies["username"].Value;

Значение cookie можно прочитать, как только через вызов метода GetResponse() получены заголовки запроса.

Заметьте, что коллекция Cookies объекта HttpWebResponse будет заполнена, только если было установлено свойство CookieContainer соответствующего HttpWebRequest. Иначе нужно считывать cookie из коллекции Headers. Записи cookie отправляются в заголовке Set-Cookie приблизительно в таком формате:

Set-Cookie: FirstName=Alexandr; path=/,LastName=Erohin; path=/
Пройди тесты
Лучший чат для C# программистов