简体   繁体   中英

C#: Post login data to form and process website's response

I am trying to write a C# program to prolong the deadline for my books in my university's library. What I want to do is the following: 1.) Login to library website via WebRequest & POST method, with username & password entered in C# program 2.) Get the url to "View borrowed books" site containing the encrypted password & plain text username as GET parameters 3.) Download content of named page to display to user in the C# program 4.) If the user presses the corresponding button in the program, submit the prolongation form to the website to prolong all media at once.

Right now I'm stuck between 1 and 2, I seem to be able to connect to the website and to enter the userdata, but the WebResponse I get is again the login page (which is not the case if you login manually on the website).

This is the method I wrote to connect to the website:

// Login function, logs the user in, uses passed user number & password
    public static Boolean userLogin(String unr, String pass)
    {
        // Login
        // Cookie needed for maintaining php session
        CookieContainer cContainer = new CookieContainer();
        Console.WriteLine(unr+","+pass);
        String postUrl = "https://universitylibrary.com/loan/DB=4/LNG=DU/USERINFO_LOGIN";
        String formParams = String.Format("ACT={0}&HOST_NAME={1}&HOST_PORT={2}&HOST_SCRIPT={3}&LOGIN={4}&STATUS={5}&BOR_U={6}&BOR_PW={7}","UI_DATA","","","","KNOWNUSER","HML_OK", unr, pass);
        String cookieHeader;
        WebRequest wreq = WebRequest.Create(postUrl);
        wreq.ContentType = "application/x-www-form-urlencoded";
        wreq.Method = "POST";
        byte[] bytes = Encoding.ASCII.GetBytes(formParams);
        wreq.ContentLength = bytes.Length;
        using (Stream os = wreq.GetRequestStream())
        {
            os.Write(bytes, 0, bytes.Length);
        }
        WebResponse resp = wreq.GetResponse();
        cookieHeader = resp.Headers["Set-cookie"];

        //Authentication trial
        String PageSource;
        String getUrl = "https://universitylibrary.com:443/loan/DB=4/USERINFO";
        WebRequest getReq = WebRequest.Create(getUrl);
        getReq.Headers.Add("Cookie",cookieHeader);
        WebResponse getResp = getReq.GetResponse();
        using (StreamReader sr = new StreamReader(getResp.GetResponseStream()))
        {
            PageSource = sr.ReadToEnd();
        }
        Console.Write(PageSource);
        return true;
    }

Can you see my mistake? I get the sourcecode and the params (username, password) output on the console, but the output is again the login page. I would just look at the php page, but I don't have access to any of the internal system data, all I have is the HTML page.

Any suggestions would be highly appreciated!

EDIT:

I have rethought the whole thing, and rebuilt the HTTP request header completely as recorded by fiddler. That part of the function looks like this now:

 // Login
        // Cookie needed for maintaining php session
        CookieContainer cContainer = new CookieContainer();
        HttpCookie cookie = new HttpCookie("cookie", "PSC_4='xxxxxxx'; DB='n'");
        CookieCollection cookieCol = new CookieCollection();
        cookieCol.Add(cookieCol);
        cContainer.Add(cookieCol);
        Console.WriteLine(unr+","+pass);
        String postUrl = "https://universitylibrary.com:443/loan/DB=4/USERINFO";
        String formParams = String.Format("ACT={0}&HOST_NAME={1}&HOST_PORT={2}&HOST_SCRIPT={3}&LOGIN={4}&STATUS={5}&BOR_U={6}&BOR_PW={7}","UI_DATA","","","","KNOWNUSER","HML_OK", unr, pass);
        String cookieHeader;
        HttpWebRequest wreq = (HttpWebRequest) WebRequest.Create(postUrl);
        wreq.Referer = "https://universitylibrary.com/loan/DB=4/LNG=DU/USERINFO_LOGIN";
        wreq.KeepAlive = true;
        wreq.ContentLength = 119;
        wreq.Host = "universitylibrary.com";
        wreq.ContentType = "application/x-www-form-urlencoded";
        wreq.Method = "POST";
        wreq.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0";
        wreq.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        wreq.SendChunked = true;
        wreq.TransferEncoding = "gzip, deflate";
        byte[] bytes = Encoding.ASCII.GetBytes(formParams);
        wreq.ContentLength = bytes.Length;
        using (Stream os = wreq.GetRequestStream())
        {
            os.Write(bytes, 0, bytes.Length);
        }
        cookieHeader = "";
        try
        {
            HttpWebResponse resp = (HttpWebResponse) wreq.GetResponse();
            cookieHeader = resp.Headers["Set-cookie"];
        }
        catch (WebException ex)
        {
            Console.WriteLine(ex.Status);
            Console.WriteLine(ex.Response);
        }

The whole thing still doesn't work though, same issue as before. Is it possible that HttpWebRequest can't handle https or that something else is missing for https to work? (HTTP & HTTPS seem to be syntactically identical and the port is correctly set to 443, the real difference seems to lay in the additional SSL/TLS layer, maybe I need to add this somewhere?)

When you are returned the login page it probably means that you have not been correctly authenticated. There could be several reasons for this, but in the end it is because you not mirroring the HTTP communication from the manual login on the website correctly.

What I usually do is to use a monitor such as Fiddler to capture the full request/response pattern from the manual login, which I can then subsequently mirror in my code.

You can just modify your login page after checking login data and make the only output is "SuccessfullySignIn", for example. If this is the data your receive, $if (getReq == "SuccessfullySignIn") { //Do something } And try to use Redirect features in your webpage

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM