Search code examples
c#sessioncookiesphpbb

Staying logged into forum


I have created a C# application that connects to a my phpBB forum and logs in. I am now trying to use a webclient to go to a page and grab the page as a string. However I keep getting logged out. How do I use the cookie created by the code used to log onto the forum, in the webclient?

Code used to log onto forum and get page:

       public static CookieContainer login(string url, string username, string password, Form1 form)
       {
           if (url.Length == 0 || username.Length == 0 || password.Length == 0)
           {
               Console.WriteLine("Information missing");
               return null;
           }

           CookieContainer myContainer = new CookieContainer();

           HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
           request.CookieContainer = myContainer;

           // Set type to POST
           request.Method = "POST";
           request.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)";
           request.ContentType = "application/x-www-form-urlencoded";

           // Build the new header, this isn't a multipart/form, so it's very simple
           StringBuilder data = new StringBuilder();
           data.Append("username=" + Uri.EscapeDataString(username));
           data.Append("&password=" + Uri.EscapeDataString(password));
           data.Append("&login=Login");

           // Create a byte array of the data we want to send
           byte[] byteData = UTF8Encoding.UTF8.GetBytes(data.ToString());

           // Set the content length in the request headers
           request.ContentLength = byteData.Length;

           Stream postStream;
           try
           {
               postStream = request.GetRequestStream();
           }
           catch (Exception e)
           {
               Console.WriteLine("Login - " + e.Message.ToString() + " (GRS)");
               return null;
           }

           // Write data
           postStream.Write(byteData, 0, byteData.Length);

           HttpWebResponse response;
           try
           {
               response = (HttpWebResponse)request.GetResponse();
           }
           catch (Exception e)
           {
               Console.WriteLine("Login - " + e.Message.ToString() + " (GR)");
               return null;
           }

           bool isLoggedIn = false;

           // Store the cookies
           foreach (Cookie c in response.Cookies)
           {
               if (c.Name.Contains("_u"))
               {
                   if (Convert.ToInt32(c.Value) > 1)
                   {
                       isLoggedIn = true;

                   }
               }
               myContainer.Add(c);
           }

           if (isLoggedIn)
           {

               string _url = "http://www.dandrews.net/forum/custom.php";
               string strResult = "";

               HttpWebRequest _request = (HttpWebRequest)HttpWebRequest.Create(_url);
               _request.CookieContainer = myContainer;
               HttpWebResponse _response = (HttpWebResponse)_request.GetResponse();



               using (StreamReader sr = new StreamReader(_response.GetResponseStream()))
               {
                   strResult = sr.ReadToEnd();
                   // Close and clean up the StreamReader
                   sr.Close();
               }
               form.userbox.Text = strResult;

               return myContainer;

           }
           else
           {
               return null;
           }
       }

Solution

  • Your using the CookieContainer differently than designed.

    CookieContainer myContainer = new CookieContainer();
    
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.CookieContainer = new CookieContainer();
    

    Should be:

    CookieContainer myContainer = new CookieContainer();
    
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.CookieContainer = myContainer;
    

    Then you can completely remove your logic to populate the container yourself because the framework will do that for you. Then just be sure to use the myContainer instance in your second request and it should work.

    Update

    If you must use the WebClient class for your second request, you may want to check out this question to help you use the CookieContainer with WebClient requests.

    Update

    Based on your updated code:

         public static CookieContainer login(string url, string username, string password)
        {
            if (url.Length == 0 || username.Length == 0 || password.Length == 0)
            {
                Console.WriteLine("Information missing");
                return null;
            }
    
            CookieContainer myContainer = new CookieContainer();
    
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.CookieContainer = myContainer;
    
            // Set type to POST
            request.Method = "POST";
            request.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)";
            request.ContentType = "application/x-www-form-urlencoded";
    
            // Build the new header, this isn't a multipart/form, so it's very simple
            StringBuilder data = new StringBuilder();
            data.Append("username=" + Uri.EscapeDataString(username));
            data.Append("&password=" + Uri.EscapeDataString(password));
            data.Append("&login=Login");
    
            // Create a byte array of the data we want to send
            byte[] byteData = UTF8Encoding.UTF8.GetBytes(data.ToString());
    
            // Set the content length in the request headers
            request.ContentLength = byteData.Length;
    
            Stream postStream;
            try
            {
                postStream = request.GetRequestStream();
            }
            catch (Exception e)
            {
                Console.WriteLine("Login - " + e.Message.ToString() + " (GRS)");
                return null;
            }
    
            // Write data
            postStream.Write(byteData, 0, byteData.Length);
    
            HttpWebResponse response;
            try
            {
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (Exception e)
            {
                Console.WriteLine("Login - " + e.Message.ToString() + " (GR)");
                return null;
            }
            string _url = "http://www.dandrews.net/forum/custom.php";
    
            // Store the cookies
            if (myContainer.GetCookies(new Uri(url)).Cast<Cookie>().Any(c => c.Name.Contains("_u")))
            {
                string strResult = "";
    
                HttpWebRequest _request = (HttpWebRequest)HttpWebRequest.Create(_url);
                _request.CookieContainer = myContainer;
                HttpWebResponse _response = (HttpWebResponse)_request.GetResponse();
    
                using (StreamReader sr = new StreamReader(_response.GetResponseStream()))
                {
                    strResult = sr.ReadToEnd();
                    // Close and clean up the StreamReader
                    sr.Close();
                }
                Console.WriteLine(strResult);
    
                return myContainer;
            }
            else
            {
                return null;
            }
        }