2009-05-30 11 views
62

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 die betreffende Seite erfordert, dass der Benutzer angemeldet ist, um auf diesen Quellcode zuzugreifen. Was mein Programm benötigt, um den Benutzer zunächst auf der Website zu loggen - nachdem ich fertig bin, kann ich auf den Quellcode zugreifen und ihn lesen.Login auf die Website, über C#

Die Website, die in protokolliert werden muss, ist: mmoinn.com/index.do?PageModule=UsersLogin

ich für den ganzen Tag gesucht haben, wie dies zu tun und Beispiele versucht, aber hatten kein Glück.

Vielen Dank im Voraus

+0

Also, ich kann von ein paar Möglichkeiten denken, dies zu tun ... Ist die C# -Programm fordern Sie den "Code" direkt vom Server über HTTP oder Sie Piggy Back auf die Browser-Anwendung oder was? Ein bisschen mehr Info wird benötigt. –

+0

Das Programm verwendet WebClient.DownloadString ("URL") –

Antwort

95

Sie können weiterhin WebClient für POST verwenden (anstelle von GET, das ist die HTTP verb, die Sie derzeit mit DownloadString verwenden), aber ich denke, Sie werden es leichter finden, mit der (geringfügig) niedrigeren Klassen WebRequest zu arbeiten und WebResponse.

Es gibt zwei Teile davon - der erste ist das Login-Formular zu posten, der zweite ist die Wiederherstellung des Headers "Set-Cookie" und das Zurücksenden an den Server als "Cookie" zusammen mit Ihrer GET-Anfrage. Der Server wird diesen Cookie verwenden, um Sie von nun an zu identifizieren (vorausgesetzt, er verwendet eine Cookie-basierte Authentifizierung, von der ich ziemlich überzeugt bin, dass diese Seite einen Set-Cookie-Header zurückgibt, der "PHPSESSID" enthält).


Buchung auf das Login-Formular

FORMULARPLZ einfach zu simulieren sind, es ist nur ein Fall Ihre Post-Daten der Formatierung wie folgt:

field1=value1&field2=value2 

Mit WebRequest und Code I angepasst Von Scott Hanselman, hier ist, wie Sie POST Daten zu Ihrem Login-Formular senden würden:

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 man in den Set-Cookie-Header für Ihr Login-Formular sehen soll:

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

gibt es die Seite hinter dem Anmeldeformular

Jetzt können Sie führen Sie Ihre GET Anfrage an eine Seite, für die Sie eingeloggt 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 der ersten POST anzeigen möchten, können Sie den HTML erholen es mit zurück:

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

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

+0

Vielen Dank für die detaillierte Antwort; aber es gibt noch einen Teil, von dem ich mir nicht sicher bin. Soll ich etwas in Bezug auf "Set-Cookie", "Cookie" oder die "PHPSESSID" ändern, die du gepostet hast? Ich habe versucht, diesen Code einfach in einem Programm zu verwenden, in dem ich meine Informationen eingab, aber es scheint mich nicht einzuloggen (ich nehme an, ich vermassele etwas mit den Cookies). –

+0

Der Code sollte OK sein, um wörtlich zu verwenden. Der Server setzt den Cookie (im Set-Cookie) und der Client (das heißt Sie) sendet den Cookie als Cookie zurück. Die erste Sache zu überprüfen ist, dass der erste POST Sie tatsächlich anmeldet, Sie finden möglicherweise der Server erwartet ein anderes Feld in Ihrem Formular POST (so seltsam wie es klingt, benötigen Sie manchmal ein leeres Feld mit dem Namen der Schaltfläche). Ich habe den Beitrag aktualisiert, um zu zeigen, wie die Ergebnisse des POST angezeigt werden. –

+0

Ich bin mir nicht sicher, was ich beim ersten Mal falsch gemacht habe, aber es funktioniert jetzt! Vielen Dank für die Hilfe. –

30

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

Aber die einzige Möglichkeit, die HttpWebRequest vor dem Senden zu erhalten, besteht darin, vom 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"); 
+0

sehr guter Code, aber funktioniert nicht gut für Ajax-Seiten – Smith

+1

funktioniert gut! andere Lösungen funktionierten nicht für meine Site! Danke – pila

+0

Beim Debuggen ist der Cookie immer leer. Die Website gibt mit Sicherheit Cookies auf den Seiten, die heruntergeladen werden. – C4u

2

Manchmal kann es helfen AllowAutoRedirect Abschalten und beide Login POST und Seite GET Anfragen denselben User-Agent-Einstellung.

request.UserAgent = userAgent; 
request.AllowAutoRedirect = false; 
6

Matthew Brindley arbeitete Code für einige Website sehr gut I (mit Login) benötigt, aber ich brauchte, um HttpWebRequest und HttpWebResponse sonst ich ein Bad Request vom Remote-Server erhalten zu ändern. Auch möchte ich meine Workaround mit Ihrem Code teilen, und ist, dass ich versuchte es auf eine Website basierend auf Moodle anmelden, aber es hat nicht funktioniert bei Ihrem Schritt "GET die Seite hinter dem Login-Formular", weil wenn erfolgreich POST der Login, der Header 'Set-Cookie' hat nichts zurückgegeben, trotz anderer Websites tut.

Also ich denke, das wo wir Cookies für nächste Anfragen speichern müssen, so fügte ich dies hinzu.


Zur "Buchung auf den Login-Formular" Codeblock:

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


und die "gibt es die Seite hinter dem Anmeldeformular":

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


Doing this, lässt mich Log mich in und erhalten Sie den Quellcode der "Seite hinter Login" (Website-basierte Moodle) Ich weiß, dies ist eine vage Verwendung der CookieContainer und HTTPCookies, weil wir zuerst fragen, gibt es eine Reihe von Cookies vor dem Senden der Anfrage an den Server gespeichert . Dies funktioniert ohne Problem sowieso, aber hier ist eine gute Informationen über WebRequest und WebResponse mit Beispielprojekten und Anleitung zu lesen:
Retrieving HTTP content in .NET
How to use HttpWebRequest and HttpWebResponse in .NET

Verwandte Themen