webentwicklung-frage-antwort-db.com.de

Einloggen auf die Website, über C #

Ich bin relativ neu in der Verwendung von C # und habe eine Anwendung, die Teile des Quellcodes auf einer Website liest. Das alles funktioniert; Das Problem ist jedoch, dass für die betreffende Seite der Benutzer angemeldet sein muss, um auf diesen Quellcode zugreifen zu können. Was mein Programm benötigt, um den Benutzer zunächst auf der Website anzumelden - danach kann ich auf den Quellcode zugreifen und ihn lesen.

Die Website, auf der Sie angemeldet sein müssen, lautet: mmoinn.com/index.do?PageModule=UsersLogin

Ich habe den ganzen Tag nach Anleitungen gesucht und Beispiele ausprobiert, aber kein Glück gehabt.

Danke im Voraus

70
Dillon

Sie können WebClient weiterhin verwenden, um POST (anstelle von GET, dem HTTP-Verb , das Sie derzeit mit DownloadString verwenden), aber ich denke, Sie werden es finden Einfacheres Arbeiten mit den (leicht) untergeordneten Klassen WebRequest und WebResponse.

Dazu gibt es zwei Teile: Der erste besteht darin, das Anmeldeformular zu senden, der zweite darin, den "Set-Cookie" -Header wiederherzustellen und diesen zusammen mit Ihrer GET-Anfrage als "Cookie" an den Server zurückzusenden. Der Server wird dieses Cookie von nun an verwenden, um Sie zu identifizieren (vorausgesetzt, es verwendet eine Cookie-basierte Authentifizierung, von der ich ziemlich sicher bin, dass diese Seite einen Set-Cookie-Header mit "PHPSESSID" zurückgibt).


POST zum Anmeldeformular

Formularbeiträge sind einfach zu simulieren. Sie müssen lediglich Ihre Beitragsdaten wie folgt formatieren:

field1=value1&field2=value2

Mit WebRequest und Code, den ich von Scott Hanselman angepasst habe, können Sie POST Formulardaten zu Ihrem Anmeldeformular hinzufügen:

string formUrl = "http://www.mmoinn.com/index.do?PageModule=UsersAction&Action=UsersLogin"; // NOTE: This is the URL the form POSTs to, not the URL of the form (you can find this in the "action" attribute of the HTML's form tag
string formParams = string.Format("email_address={0}&password={1}", "your email", "your password");
string cookieHeader;
WebRequest req = WebRequest.Create(formUrl);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(formParams);
req.ContentLength = bytes.Length;
using (Stream os = req.GetRequestStream())
{
    os.Write(bytes, 0, bytes.Length);
}
WebResponse resp = req.GetResponse();
cookieHeader = resp.Headers["Set-cookie"];

Hier ist ein Beispiel dafür, was Sie im Set-Cookie-Header für Ihr Anmeldeformular sehen sollten:

PHPSESSID=c4812cffcf2c45e0357a5a93c137642e; path=/; domain=.mmoinn.com,wowmine_referer=directenter; path=/; domain=.mmoinn.com,lang=en; path=/;domain=.mmoinn.com,adt_usertype=other,adt_Host=-

Die Seite hinter dem Anmeldeformular aufrufen

Jetzt können Sie Ihre GET-Anfrage an eine Seite senden, für die Sie angemeldet sein müssen.

string pageSource;
string getUrl = "the url of the page behind the login";
WebRequest getRequest = WebRequest.Create(getUrl);
getRequest.Headers.Add("Cookie", cookieHeader);
WebResponse getResponse = getRequest.GetResponse();
using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
{
    pageSource = sr.ReadToEnd();
}

EDIT:

Wenn Sie die Ergebnisse des ersten POST anzeigen möchten, können Sie den zurückgegebenen HTML-Code wiederherstellen:

using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
    pageSource = sr.ReadToEnd();
}

Platziere dies direkt unter cookieHeader = resp.Headers["Set-cookie"]; und überprüfen Sie dann die in pageSource enthaltene Zeichenfolge.

103
Matt Brindley

Sie können die Dinge erheblich vereinfachen, indem Sie eine Klasse erstellen, die von WebClient abgeleitet ist, die GetWebRequest-Methode überschreibt und ein CookieContainer-Objekt darauf setzt. Wenn Sie immer dieselbe CookieContainer-Instanz festlegen, wird die Cookie-Verwaltung automatisch für Sie durchgeführt.

Die einzige Möglichkeit, auf die HttpWebRequest zuzugreifen, bevor sie gesendet wird, besteht darin, von WebClient zu erben und diese Methode zu überschreiben.

public class CookieAwareWebClient : WebClient
{
    private CookieContainer cookie = new CookieContainer();

    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest request = base.GetWebRequest(address);
        if (request is HttpWebRequest)
        {
            (request as HttpWebRequest).CookieContainer = cookie;
        }
        return request;
    }
}

var client = new CookieAwareWebClient();
client.BaseAddress = @"https://www.site.com/any/base/url/";
var loginData = new NameValueCollection();
loginData.Add("login", "YourLogin");
loginData.Add("password", "YourPassword");
client.UploadValues("login.php", "POST", loginData);

//Now you are logged in and can request pages    
string htmlSource = client.DownloadString("index.php");
34
Josh

Matthew Brindley , Ihr Code hat für einige von mir benötigte Websites (mit Login) sehr gut funktioniert, aber ich musste zu HttpWebRequest und HttpWebResponse wechseln, sonst erhalte ich ein 404 Bad Request vom Remote-Server. Außerdem möchte ich meine Problemumgehung mit Ihrem Code teilen und habe versucht, mich bei einer Website basierend auf Moodle anzumelden, aber es hat bei Ihrem Schritt nicht funktioniert " ERHALTE die Seite hinter dem Login-Formular "weil bei erfolgreichem POSTING Login der Header 'Set-Cookie' hat trotz anderer Websites nichts zurückgegeben.

Also denke ich, dass wir hier Cookies für die nächsten Anfragen speichern müssen, also habe ich dies hinzugefügt.


Zum " POSTing zum Anmeldeformular " Codeblock:

var cookies = new CookieContainer();
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(formUrl);
req.CookieContainer = cookies;


Und zum " ABRUFEN der Seite hinter dem Anmeldeformular ":

HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(getUrl);
getRequest.CookieContainer = new CookieContainer();
getRequest.CookieContainer.Add(resp.Cookies);
getRequest.Headers.Add("Cookie", cookieHeader);


Wenn Sie dies tun, lassen Sie mich Log me in und den Quellcode der "Seite hinter dem Login" (website based moodle) erhalten. Ich weiß, dass dies eine vage Verwendung des CookieContainer und HTTPCookies, da wir möglicherweise zuerst fragen, ob zuvor gesicherte Cookies vorhanden sind, bevor die Anfrage an den Server gesendet wird. Dies funktioniert ohnehin problemlos, aber hier finden Sie eine gute Information zu WebRequest und WebResponse mit Beispielprojekten und Lernprogramm:
Abrufen von HTTP-Inhalten in .NET
Verwendung von HttpWebRequest und HttpWebResponse in .NET

8
WhySoSerious

Manchmal kann es hilfreich sein, AllowAutoRedirect auszuschalten und beim Festlegen von Login POST und Page GET denselben Benutzeragenten anzufordern.

request.UserAgent = userAgent;
request.AllowAutoRedirect = false;
2
TN.