¿Cómo puedo reutilizar las cookies de HttpWebResponse para permanecer conectado en una página web?

c# cookies html-agility-pack httpwebrequest wpf

Pregunta

Tengo un caso con una aplicación simple que navega a un sitio del Foro de XenForo, busca cookies y envía datos posteriores para iniciar sesión y obtener información que solo está disponible para usuarios registrados.

Puedo recuperar con éxito las cookies y verificar que haya iniciado sesión correctamente la primera vez, pero parece que no puedo mantener la sesión iniciada cuando intento "navegar" más cuando intento reutilizar las mismas cookies.

Aquí está lo que tengo hasta ahora:

public MainWindow()
{
    InitializeComponent();
    if (IsLoggedIn())
    {
        GetPage("http://thesiteiloginto.org/someotherpage");
    }
}

// Store Cookies
CookieCollection Cookies;

void GetCookies(string cookieUrl)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(cookieUrl);
    request.CookieContainer = new CookieContainer();
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    using (Stream responseStream = response.GetResponseStream())
    {
        // Store Cookies
        Cookies = response.Cookies;
    }
}

bool IsLoggedIn()
{
    GetCookies(_cookieUrl);
    CookieCollection cookies = Cookies;
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(loginUrl);
    request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)";
    request.CookieContainer = new CookieContainer();
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    string postData = "login=" + username +
                        "&password=" + password +
                        "&_xfToken=" + xfToken +
                        "&cookie_check=" + cookie_check +
                        "&redirect=" + redirect;
    byte[] bytes = Encoding.UTF8.GetBytes(postData);
    request.ContentLength = bytes.Length;
    if (cookies != null)
    {
        Console.WriteLine("Cookies are present");
        Console.WriteLine(Cookies.Count);
        Console.WriteLine(Cookies[0].Value);
        request.CookieContainer.Add(cookies);
    }
    using (Stream requestStream = request.GetRequestStream())
    {
        requestStream.Write(bytes, 0, bytes.Length);
        WebResponse response = request.GetResponse();
        using (Stream stream = response.GetResponseStream())
        {
            using (StreamReader reader = new StreamReader(stream))
            {
                HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
                doc.LoadHtml(reader.ReadToEnd());
                bool _loggedIn = false;
                try
                {
                    var uniqueNodeTest = doc.DocumentNode.SelectSingleNode("//*[@id=\"navigation\"]/div/nav/div/ul[2]/li[1]/a/strong[1]");
                    if (uniqueNodeTest.InnerText.Trim().ToLower() == uniqueNodeName)
                    {
                        Console.WriteLine("Logged in");
                        _loggedIn = true;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Ops! [Login] @ SelectSingleNode\n" + ex.Message);
                    _loggedIn = false;
                }
                return _loggedIn;
            }
        }
    }
}

void GetPage(string url)
{
    if (Cookies != null)
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.PreAuthenticate = true;
        request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)";
        request.CookieContainer = new CookieContainer();
        request.CookieContainer.Add(Cookies);
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        using (Stream responseStream = response.GetResponseStream())
        {
            using (StreamReader reader = new StreamReader(responseStream))
            {
                var pageSource = reader.ReadToEnd();

                // Retuns false, meaning i am not logged in
                //Where do i go from here?
                Console.WriteLine(pageSource.Contains("Log Out"));
            }
        }
    }
}

Consola:

Cookies are present 1 22a6c5a4c5557a7f7db36f50a1d746f1 Logged in False

Como puede ver, inicié sesión después de la primera prueba, pero parece que no puedo mantenerme conectado cuando intento seguir navegando y reutilizando las cookies.

¿Qué no estoy tomando en consideración? ¿Cómo puedo permanecer conectado en el sitio?

Respuesta aceptada

Utilice CookieContainer como clase para almacenarlos localmente.

Al recuperar la respuesta, coloque todas sus cookies en el CookieContainer. Al preparar la solicitud, simplemente configure la solicitud. CookieContainer en su propio objeto en la nueva llamada.

Este es el código que utilicé para guardar mis cookies en un proyecto mío. Ya que es parte de una clase HttpSession completamente diseñada específicamente para el tipo de solicitudes que está realizando, notará que tanto la respuesta como el contenedor de cookies son variables de clase.

/// <summary>
///     Fetches the new cookies and saves them in the cookie jar.
/// </summary>
private void SaveNewCookies()
{
    try
    {
        foreach (Cookie c in this.m_HttpWebResponse.Cookies)
        {
            if (c.Domain.Length > 0 && c.Domain[0] == '.')
                c.Domain = c.Domain.Remove(0, 1);
            this.m_CookieJar.Add(new Uri(this.m_HttpWebResponse.ResponseUri.Scheme + "://" + c.Domain), c);
        }
        if (this.m_HttpWebResponse.Cookies.Count > 0)
            this.BugFixCookieDomain(this.m_CookieJar);
    }
    catch
    {
        // no new cookies
    }
}

Como ves, esto también contiene algunas correcciones de errores más pequeños. La mencionada función BugFixCookieDomain es una solución específica para el marco 3.5, que puede encontrar aquí , pero si se ha movido más allá de la 4.0 y más allá, no será particularmente útil para usted.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué