Http-клиент, способный принимать cookie-файлы

#c# #cookies #httpclient

#c# #файлы cookie #httpclient

Вопрос:

Я пытаюсь получить доступ ba.com (фактический URL: «https://www.britishairways.com/travel/loginr/public/en_us?eId=109001 ) выполняя POST с требуемыми параметрами, он отвечает перенаправлением 3XX, которое указывает на URL https://www.britishairways.com/cookie.html с Set-Cookie заголовком. Я пытаюсь выполнить GET, используя заголовок запроса Cookie с key=value;key=value ... помощью, на этом этапе он возвращает 2XX сообщение о том, что cookie не включен.

Для gmail.com он напрямую возвращает ответ 2XX с Set-Cookie заголовком, когда я создаю сообщение с требуемыми параметрами, и объявляет, что cookie не включен.

Мои вопросы:

  1. Какими обычно должны быть HTTP-последовательности между клиентом и сервером для проверки того, что cookie-файлы включены?
  2. Моя общая цель — получить доступ к моей учетной записи через программу, войти в систему и проверить некоторую информацию о моей учетной записи. britshairways.com/gmail.com могло бы стать хорошим началом. (Это похоже на имитацию веб-браузера)

Если кто-нибудь знает примеры кодов, которые могли бы выполнить задачу, я хотел бы научиться. Спасибо.

Ниже приведены нерабочие примеры кодов с подробными параметрами для вызова britishairways.com/gmail.com

 public static void PostToUrlWithCookies(string uri, NameValueCollection nvc, CookieCollection cookies, string cookieHeader = "")
{
    // this is what we are sending
    string post_data = "";
    if (nvc != null)
    {
        foreach (string key in nvc.Keys)
        {
            string formitem = string.Format("{0}={1}", key, nvc[key]);
            if (post_data == "")
            {
                post_data  = formitem;
            }
            else
            {
                post_data  = "amp;"   formitem;

            }
        }
    }
    Console.WriteLine("post_data={0}", post_data);


    // create a request
    HttpWebRequest request = (HttpWebRequest)
    WebRequest.Create(uri);

    // to accept cookies (and skip 100 response)
    //var cookies = new CookieContainer(); 
    ServicePointManager.Expect100Continue = false;

    string newCookieHeader = "";
    request.CookieContainer = new CookieContainer();
    if (cookies.Count > 0)
    {
        CookieCollection oCookies = cookies;

        for (int j = 0; j < oCookies.Count; j  )
        {
            Cookie oCookie = oCookies[j];
            Cookie oC = new Cookie();

            // Convert between the System.Net.Cookie to a System.Web.HttpCookie...
            oC.Domain = request.RequestUri.Host;
            oC.Expires = oCookie.Expires;
            oC.Name = oCookie.Name;
            oC.Path = oCookie.Path;
            oC.Secure = oCookie.Secure;
            oC.Value = oCookie.Value;

            if (newCookieHeader != "")
            {
                newCookieHeader  = ";";
            }
            newCookieHeader  = oC.Name   "="   oC.Value;

            //request.CookieContainer.Add( oC );
        }

    }


    //      Console.WriteLine("request has {0} cookies inside", request.CookieContainer.Count);

    if (cookieHeader != "")
    {
        request.Headers["Cookie"] = newCookieHeader;
        Console.WriteLine("request Set-Cookie: {0}", newCookieHeader);
    }


    // add a fake cookie to request
    //Cookie aCookie = new Cookie("lastVisited", DateTime.Now.ToString());
    //aCookie.Domain = "ba.com";
    //request.CookieContainer.Add(aCookie);

    request.KeepAlive = true;
    request.ProtocolVersion = HttpVersion.Version11;
    if (cookies.Count == 0)
    {
        request.AllowAutoRedirect = false;   // ba.com testing cookies using a 3XX Redirect
        request.Method = "POST";
    }
    else
    {
        request.AllowAutoRedirect = false;
        request.Method = "GET";
    }
    //    
    // turn our request string into a byte stream
    byte[] postBytes = Encoding.ASCII.GetBytes(post_data);

    // this is important - make sure you specify type this way
    if (request.Method == "POST")
    {
        request.ContentType = "application/x-www-form-urlencoded";
        request.UserAgent = "Mozilla/5.0 (X11; Linux x86_64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2";
        request.ContentLength = postBytes.Length;
        Stream requestStream = request.GetRequestStream();
        //      
        //      // now send it
        if (post_data != "")
        {
            requestStream.Write(postBytes, 0, postBytes.Length);
        }
        requestStream.Close();
    }
    else
    {
        request.UserAgent = "Mozilla/5.0 (X11; Linux x86_64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2";
    }

    //       
    // grab te response and print it out to the console along with the status code
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    foreach (Cookie cook in response.Cookies)
    {
        //               Console.WriteLine("Cookie:");
        //              Console.WriteLine("{0} = {1}", cook.Name, cook.Value);
        cookies.Add(cook);
    }

    cookieHeader = response.GetResponseHeader("Set-Cookie");
    Console.WriteLine("responce-> Set-Cookie: {0}", cookieHeader);


    for (int i = 0; i < response.Headers.Count;   i)
        Console.WriteLine("nHeader Name:{0}, Value :{1}", response.Headers.Keys[i], response.Headers[i]);


    if ((int)response.StatusCode >= 300 amp;amp; (int)response.StatusCode < 400)
    {
        string cookieUrl = response.Headers["Location"];
        Console.WriteLine("about to verify cookie via url {0}", cookieUrl);




        // verify the cookie capability
        PostToUrlWithCookies(cookieUrl, null /*nvc*/, cookies, cookieHeader);
    }
    else
    {
        Console.WriteLine(new StreamReader(response.GetResponseStream()).ReadToEnd());
        Console.WriteLine((int)response.StatusCode);

    }


}
  

вызовите ba.com (формат: пары uri, ключ, значение):

 func "https://www.britishairways.com/travel/loginr/public/en_us?eId=109001","loginText", "Login ID", "Directional_Login", "/travel/echome/execclub/en_us?membershipNumber=36436959&DM1%5FmktgCat=Email&DM1%5FMktgSubCat=2&DM1%5Fcampaign=BBBB5YT0BPKCBBBB5YT0BQBG&DM1%5FChksm=117285700&DM1_SRC=&utm_source=eD&utm_medium=Email&utm_campaign=Email&utm_term=BBBB5YT0BQBG&utm_content=BBBB5YT0BPKC", "membershipNumber", "XXXXXX", "password", "XXXXXX", "passwordtext", "XXXXXXX" 
  

вызовите gmail.com

 "https://accounts.google.com/ServiceLoginAuth", "continue", "http://www.google.com/", "dsh", "7157339180374789215", "hl", "en", "GALX", "f9V9sU8AY6c", "pstMsg", "1", "dnConn", "", "timeStmp", "", "secTok", "", "Email", "XXXXXXX@gmail.com", "Passwd", "XXXXXXX", "signIn", "Sign in", "rmShown", "1"
  

Комментарии:

1. Вы пробовали WebClient ? Не уверен, есть ли у него встроенная поддержка cookie, но я думаю, что да

2. К какому классу / библиотеке вы используете доступ https://www.ba.com . Как выглядит ваш код?

3. Для протокола, это противоречит условиям предоставления услуг веб-сайта: «В частности, Вы соглашаетесь с тем, что Вы не должны … использовать «очистку экрана», любой автоматизированный алгоритм, устройство, метод, систему, программное обеспечение или ручной процесс для доступа, использования, поиска, копирования, мониторинга или извлечения материалов (полностью или частично) с или посредством использования этого веб-сайта, если мы не дали нашего прямого письменного согласия;» britishairways.com/travel/termcn/public/en_us

4. Я также отмечаю, что ba.com имеет проблемы с безопасностью, поскольку сертификат не соответствует домену ( ba.com перенаправляет на britishairways.com но ba.com делает неправильную вещь и пытается обслуживать тот же контент.), ошибки сертификата могут вызвать проблемы с WebClient или WebRequest

5. На самом деле я использовал » britishairways.com «, смотрите список параметров в сообщении. Извините за путаницу, это не ba.com Я поместил его туда просто для удобства.

Ответ №1:

Добавление поддержки cookie в WebRequest — это несколько строк кода.

 var cookies = new CookieContainer();

// perform normal request;
var webResponse; // be sure this gets assigned

cookies.Add(webResponse.Cookies);

// create another request
var webRequest; // be sure this gets assigned

webRequest.CookiesContainer = cookies;

// perform next request. This time with cookies.
  

Комментарии:

1. Это правильно, но будьте осторожны — я использовал его много лет назад, и я думаю, что столкнулся с некоторыми неясными (но пагубными) ошибками. Возможно, они уже исправили это, но покупатель остерегается 🙂

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

3. О, нет сомнений, что это работает в тривиальных случаях — я использовал это, чтобы очистить несколько тысяч уникальных веб-сайтов, когда столкнулся с этим ;). Но в большинстве случаев это должно быть более чем нормально (таким образом, 1)

4. @Stargazer712 Я понял, что вы имели в виду именно это, но не хотел отпугивать нового пользователя его первым вопросом.

5. Пожалуйста, взгляните на мою реализацию ниже, которая не работает