2009-08-15 11 views
5

Potrzebuję wykonać pewne działania w panelu administracyjnym wordpress programowo, ale nie mogę zarządzać, jak zalogować się do Wordpress przy użyciu C# i HttpWebRequest.Jak programowo logować się do wordpressa?

Oto co mam zrobić:

private void button1_Click(object sender, EventArgs e) 
     { 
      string url = "http://localhost/wordpress/wp-login.php"; 
      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
      CookieContainer cookies = new CookieContainer(); 

      SetupRequest(url, request, cookies); 
      //request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; 
      //request.Headers["Accept-Language"] = "uk,ru;q=0.8,en-us;q=0.5,en;q=0.3"; 
      //request.Headers["Accept-Encoding"] = "gzip,deflate"; 
      //request.Headers["Accept-Charset"] = "windows-1251,utf-8;q=0.7,*;q=0.7"; 


      string user = "test"; 
      string pwd = "test"; 

      request.Credentials = new NetworkCredential(user, pwd); 

      string data = string.Format(
       "log={0}&pwd={1}&wp-submit={2}&testcookie=1&redirect_to={3}", 
       user, pwd, 
       System.Web.HttpUtility.UrlEncode("Log In"), 
       System.Web.HttpUtility.UrlEncode("http://localhost/wordpress/wp-admin/")); 

      SetRequestData(request, data); 

      ShowResponse(request); 
} 

private static void SetupRequest(string url, HttpWebRequest request, CookieContainer cookies) 
     { 
      request.CookieContainer = cookies; 
      request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.0; uk; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)"; 
      request.KeepAlive = true; 
      request.Timeout = 120000; 
      request.Method = "POST"; 
      request.Referer = url; 
      request.ContentType = "application/x-www-form-urlencoded"; 
     } 

     private void ShowResponse(HttpWebRequest request) 
     { 
      HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
      responseTextBox.Text = (((HttpWebResponse)response).StatusDescription); 
      responseTextBox.Text += "\r\n"; 
      StreamReader reader = new StreamReader(response.GetResponseStream()); 
      responseTextBox.Text += reader.ReadToEnd(); 
     } 

     private static void SetRequestData(HttpWebRequest request, string data) 
     { 
      byte[] streamData = Encoding.ASCII.GetBytes(data); 
      request.ContentLength = streamData.Length; 

      Stream dataStream = request.GetRequestStream(); 
      dataStream.Write(streamData, 0, streamData.Length); 
      dataStream.Close(); 
     } 

Ale niestety w responce mam tylko HTML kod źródłowy strony logowania i wydaje się, że cookies nie zawierają identyfikator sesji. Wszystkie żądania, które wykonuję po tym kodzie, również zwracają źródło HTML strony logowania, więc mogę założyć, że nie loguje się poprawnie.

Czy ktoś może mi pomóc rozwiązać ten problem lub podać przykład pracy?


Najważniejsze, co chcę osiągnąć, to skanowanie w poszukiwaniu nowych obrazów w pluginach Nextgen Gallery dla Wordpress. Czy istnieje sposób na XML-RPC?

Z góry dziękuję.

Odpowiedz

1

Dziękuję wszystkim. Udało mi się sprawić, żeby działało to tylko przy użyciu gniazd. Wordpress wysyła kilka nagłówków Set-Cookie, ale HttpWebRequest obsługuje tylko jedną instancję takiego nagłówka, więc niektóre pliki cookie są tracone. Korzystając z gniazd mogę uzyskać wszystkie potrzebne pliki cookie i zalogować się do panelu administracyjnego.

+1

Niektóre kod byłby być złe, jak inne ludzie mogą też szukać rozwiązania (takiego jak ja). To jest kwestia forum ... – C4u

+0

Tak okrutny! dlaczego nie ma rozwiązania? –

+0

to jest zaakceptowana odpowiedź? brak kodu? – DidIReallyWriteThat

1

Nie widzę oczywistego problemu z Twoim kodem, przepraszam. Ale Wordpress ma interfejs XML-RPC, który musi być włączony w interfejsie administratora. Napisałem kilka skryptów Pythona dla tego interfejsu i działało jak czar.

0

Próbowałem tego z moim kontem WordPress.com (chronionym protokołem SSL). Odkryłem, że najłatwiej jest użyć gniazd .NET, aby uzyskać nagłówki HTTP "Set-Cookie", a następnie przeanalizować nagłówki obiektów .NET Cookie, a następnie użyć do pliku CookieContainer z plikami cookie dla HttpWebRequest.

Najprostszym sposobem na pracę z SSL przez gniazda jest zaimplementowanie SslStream przez NetworkStream związany z gniazdem.

przykład:

private void LogIn() 
    { 
     string fulladdress = "hostname.wordpress.com"; 
     string username = HttpUtility.UrlEncode("username"); 
     string password = HttpUtility.UrlEncode("password"); 

     string formdata = "log={0}&pwd={1}&redirect_to=http%3A%2F%2F{2}%2Fwp-admin%2F&testcookie=1"; 
     formdata = string.Format(formdata, username, password, fulladdress); 
     IPHostEntry entry = Dns.GetHostEntry(fulladdress); 


     Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); 
     s.Connect(entry.AddressList[0], 443); 

     NetworkStream ns = new NetworkStream(s); 

     System.Net.Security.SslStream ssl = new System.Net.Security.SslStream(ns); 
     byte[] data = Encoding.UTF8.GetBytes(String.Format(WpfApplication2.Properties.Resources.LogRequest, "https://" + fulladdress, fulladdress, form.Length, username, password)); 

     ssl.AuthenticateAsClient(fulladdress); 
     ssl.Write(data, 0, data.Length); 

     StringBuilder sb = new StringBuilder(); 
     byte[] resp = new byte[128]; 
     int i = 0; 
     while (ssl.Read(resp, 0, 128) > 0) 
     { 
      sb.Append(Encoding.UTF8.GetString(resp)); 
     } 

     List<String> CookieHeaders = new List<string>(); 
     foreach (string header in sb.ToString().Split("\n\r".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)) 
     { 
      if (header.StartsWith("Set-Cookie")) 
      { 
       CookieHeaders.Add(header.Replace("Set-Cookie: ", "")); 
      } 
     } 

     CookieContainer jar = new CookieContainer(); 
     foreach (string cook in CookieHeaders) 
     { 
      string name, value, path, domain; 
      name = value = path = domain = ""; 

      string[] split = cook.Split(';'); 
      foreach (string part in split) 
      { 
       if (part.StartsWith(" path=")) 
       { 
        path = part.Replace(" path=", ""); 
       } 
       if (part.StartsWith(" domain=")) 
       { 
        domain = part.Replace(" domain=", ""); 
       } 
       if (!part.StartsWith(" path=") && !part.StartsWith(" domain=") && part.Contains("=")) 
       { 
        name = part.Split('=')[0]; 
        value = part.Split('=')[1]; 
       } 
      } 

      jar.Add(new Cookie(name, value, path, domain)); 
     } 

     HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://" + fulladdress + "/wp-admin/index.php"); 
     req.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3"; 
     req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; 
     req.KeepAlive = false; 
     req.AllowAutoRedirect = false; 
     req.Referer = "https://" + fulladdress + "/wp-login.php"; 
     req.ContentType = "application/x-www-form-urlencoded"; 
     req.CookieContainer = jar; 
     req.AllowAutoRedirect = true; 
     req.AutomaticDecompression = DecompressionMethods.GZip; 
     req.Method = "GET"; 
     req.Timeout = 30000; 

     HttpWebResponse response = (HttpWebResponse)req.GetResponse(); 

     using (System.IO.StreamReader sr = new System.IO.StreamReader(response.GetResponseStream(), Encoding.UTF8)) 
     { 
      MessageBox.Show(sr.ReadToEnd()); 
     } 
    } 

Kod nie jest bardzo wydajne, ale ilustruje proces logowania do interfejsu zarządzania.

Nadzieja to pomaga :)

1
NameValueCollection loginData = new NameValueCollection(); 
loginData.Add("username", "your_username"); 
loginData.Add("password", "your_password"); 

WebClient client = new WebClient(); 
string source = Encoding.UTF8.GetString(client.UploadValues("http://www.site.com/login", loginData)); 

string cookie = client.ResponseHeaders["Set-Cookie"]; 
3

Nie wiem, czy inni będą mogli to pomocne, ale po prostu stosować WordPress API do logowania. Stworzyłem użytkownika (CRON_USR), który loguje się” "w nocy jako część pracy cron i wykonuje pewne zadania. Kod jest to:

require(dirname(__FILE__) . '/wp-load.php'); 
$user = wp_authenticate(CRON_USR, CRON_PWD); 
wp_set_auth_cookie($user->ID, true, $secure_cookie); //$secure_cookie is an empty string 
do_action('wp_login', CRON_USR); 
wp_redirect('http://www.mysite.com/wp-admin/'); 
5

Ponieważ WordPress wdrożyć przekierowanie, pozostawiając stronę (przekierowanie) zapobiega WebRequest z coraz prawidłowego ciasteczko.

Aby uzyskać odpowiedni plik cookie, należy zapobiec przekierowaniom.

request.AllowAutoRedirect = false; 

niż używać cookie-conatainer do logowania.

patrz poniższy kod: (w oparciu o przykład z C# książki Albahari'S)

 string loginUri = "http://www.someaddress.com/wp-login.php"; 
     string username = "username"; 
     string password = "pass"; 
     string reqString = "log=" + username + "&pwd=" + password; 
     byte[] requestData = Encoding.UTF8.GetBytes(reqString); 

     CookieContainer cc = new CookieContainer(); 
     var request = (HttpWebRequest)WebRequest.Create(loginUri); 
     request.Proxy = null; 
     request.AllowAutoRedirect = false; 
     request.CookieContainer = cc; 
     request.Method = "post"; 

     request.ContentType = "application/x-www-form-urlencoded"; 
     request.ContentLength = requestData.Length; 
     using (Stream s = request.GetRequestStream()) 
      s.Write(requestData, 0, requestData.Length); 

     using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
     { 
      foreach (Cookie c in response.Cookies) 
       Console.WriteLine(c.Name + " = " + c.Value); 
     } 

     string newloginUri = "http://www.someaddress.com/private/"; 
     HttpWebRequest newrequest = (HttpWebRequest)WebRequest.Create(newloginUri); 
     newrequest.Proxy = null; 
     newrequest.CookieContainer = cc; 
     using (HttpWebResponse newresponse = (HttpWebResponse)newrequest.GetResponse()) 
     using (Stream resSteam = newresponse.GetResponseStream()) 
     using (StreamReader sr = new StreamReader(resSteam)) 
      File.WriteAllText("private.html", sr.ReadToEnd()); 
     System.Diagnostics.Process.Start("private.html"); 
0

TomerBu ma najlepszą odpowiedzią dla mnie, ale czegoś brakowało.

w swoim kodzie, remplace:

foreach (Cookie c in response.Cookies) 
      Console.WriteLine(c.Name + " = " + c.Value); 

przez

if (response.Cookies != null) 
    { 
     foreach (Cookie currentcook in response.Cookies) 
      request.CookieContainer.Add(currentcook); //This is the key !!! 
    } 

Następny na życzenie Futur, będziesz musiał ponownie użyć CookieContainer.

0

W celu programowo logowania do WordPress na udostępnionym hosta (cPanel) TomerBu's odpowiedź wystarczyły dla mnie z jednej Ponadto: UserAgent musi być zdefiniowana w następujący sposób

... 
request.Proxy = null; 
request.AllowAutoRedirect = false; 
request.CookieContainer = cc; 
request.Method = "post"; 


// Add UserAgent 
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"; 
Powiązane problemy