Comment puis-je réutiliser les cookies de HttpWebResponse pour rester connecté à une page Web?

c# cookies html-agility-pack httpwebrequest wpf

Question

J'ai un cas avec une application simple qui navigue sur un site du forum XenForo, récupère les cookies et envoie en outre des données de publication pour vous connecter et récupère des informations uniquement disponibles pour les utilisateurs connectés.

Je parviens à récupérer les cookies et à vérifier que je suis connecté avec succès la première fois, mais je n'arrive pas à rester connecté lorsque j'essaie de "parcourir" davantage lorsque je tente de réutiliser les mêmes cookies.

Voici ce que j'ai eu jusqu'à présent:

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"));
            }
        }
    }
}

Console:

Cookies are present 1 22a6c5a4c5557a7f7db36f50a1d746f1 Logged in False

Comme vous pouvez le constater, je suis connecté après le premier test, mais je ne peux pas sembler rester connecté lorsque j'essaie de naviguer davantage en réutilisant les cookies.

Qu'est-ce que je ne prends pas en considération? Comment puis-je rester connecté au site?

Réponse acceptée

Utilisez CookieContainer tant que classe pour les stocker localement.

Lors de la récupération de la réponse, placez tous vos cookies dans le CookieContainer. Lors de la préparation de la demande, définissez simplement request.CookieContainer sur votre propre objet lors du nouvel appel.

C'est le code que j'ai utilisé pour enregistrer mes cookies dans un de mes projets. Étant donné qu’elle fait partie d’une classe HttpSession totalement intégrée, spécialement conçue pour le type de demandes que vous effectuez, vous remarquerez que la réponse et le conteneur de cookies sont des variables de classe.

/// <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
    }
}

Comme vous le voyez, il contient également quelques corrections de bogues plus petites. La fonction BugFixCookieDomain mentionnée est un correctif spécifiquement pour le framework 3.5, que vous pouvez trouver ici , mais si vous avez dépassé cette version pour 4.0 et les versions ultérieures, elle ne vous sera pas particulièrement utile.



Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow