0

I have a case with a simple application that browses to a XenForo Forum site, fetches cookies and further sends post data to login and fetch some information only available for logged in users.

I am able to successfully fetch the cookies and verify that i am successfully logged in the first time, but i cant seem to stay logged in when i try to "browse" further when trying to reuse the same cookies.

Here is what i got so far:

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

As you can see i am logged in after the first test, but i cant seem to stay logged in when trying to further browse reusing the cookies.

What am i not taking into consideration? How can i stay logged in to the site?

Dan-Levi Tømta
  • 796
  • 3
  • 14
  • 29
  • I've done this before using the `CookieContainer` as class to store them locally. Then you can just set the `request.CookieContainer` to your own object on the new call. Do consider though, it might be your "logged in" test that's failing. Did you try that out on a saved HTML from the final logged in page? I personally usually use regex for a quick and dirty check like that; the surroundings of the username are usually pretty fixed. – Nyerguds Apr 11 '16 at 14:26
  • Awesome! I have used CookieCollection when i should have used CookieContainer. It works now thanks! Make it an answer and ill accept it. – Dan-Levi Tømta Apr 11 '16 at 14:35

1 Answers1

2

Use CookieContainer as class to store them locally.

When retrieving the response, put all your cookies into the CookieContainer. When preparing the request, just set the request.CookieContainer to your own object on the new call.

This is the code I used for saving my cookies in a project of mine. Since it's part of one fully decked out HttpSession class specifically meant for the kind of requests you're doing, you'll notice both the response and the cookie container are class variables.

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

As you see, this contains some smaller bug fixes as well. The mentioned BugFixCookieDomain function is a fix specifically for the 3.5 framework, which you can find here, but if you've moved past that to 4.0 and beyond it won't be particularly useful to you.

Community
  • 1
  • 1
Nyerguds
  • 5,360
  • 1
  • 31
  • 63
  • If you're interested... the full version of that class (GPL-licensed, due to the project it was originally part of) is somewhere in [this project](http://nyerguds.arsaneus-design.com/project_stuff/2016/ComicDownloader/dev/). – Nyerguds Apr 11 '16 at 15:10
  • That i s very useful. What i did was in the GetCookies method i saved the Cookies out in the Global scope and the reused those cookies for all the other methods. Works like a charm. – Dan-Levi Tømta Apr 11 '16 at 15:20