Wie kann ich Cookies von HttpWebResponse wiederverwenden, um auf einer Webseite eingeloggt zu bleiben?

c# cookies html-agility-pack httpwebrequest wpf

Frage

Ich habe einen Fall mit einer einfachen Anwendung, die zu einer XenForo Forum-Website durchsucht, Cookies abruft und weiter Postdaten zur Anmeldung sendet und einige Informationen abruft, die nur für angemeldete Benutzer verfügbar sind.

Ich bin in der Lage, die Cookies erfolgreich zu holen und zu überprüfen, dass ich mich beim ersten Mal erfolgreich angemeldet habe, aber ich kann nicht eingeloggt bleiben, wenn ich versuche, weiter zu "browsen", wenn ich versuche, dieselben Cookies wiederzuverwenden.

Hier ist, was ich bis jetzt bekommen habe:

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

Konsole:

Cookies are present 1 22a6c5a4c5557a7f7db36f50a1d746f1 Logged in False

Wie Sie sehen können, bin ich nach dem ersten Test angemeldet, aber ich kann anscheinend nicht eingeloggt bleiben, wenn ich versuche, die Cookies erneut zu durchsuchen.

Was beachte ich nicht? Wie kann ich auf der Website eingeloggt bleiben?

Akzeptierte Antwort

Verwenden Sie CookieContainer als Klasse, um sie lokal zu speichern.

Wenn Sie die Antwort erhalten, legen Sie alle Ihre Cookies in den CookieContainer. Wenn Sie die Anfrage vorbereiten, setzen Sie einfach den Request.CookieContainer auf Ihr eigenes Objekt für den neuen Anruf.

Dies ist der Code, mit dem ich meine Cookies in einem meiner Projekte gespeichert habe. Da es Teil einer voll ausgestatteten HttpSession-Klasse ist, die speziell für die Art von Anforderungen gedacht ist, die Sie tun, werden Sie feststellen, dass sowohl die Antwort als auch der Cookie-Container Klassenvariablen sind.

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

Wie Sie sehen, enthält dies einige kleinere Fehlerbehebungen. Die erwähnte BugFixCookieDomain-Funktion ist ein Fix speziell für das 3.5-Framework, das Sie hier finden können, aber wenn Sie darüber hinaus zu 4.0 und darüber hinaus gegangen sind, wird es Ihnen nicht besonders nützlich sein.



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum