2009-08-15 7 views
5

J'ai besoin d'effectuer certaines actions dans le panneau d'administration wordpress par programmation, mais je n'arrive pas à gérer comment me connecter à Wordpress en utilisant C# et HttpWebRequest.Comment se connecter à wordpress par programme?

Voici ce que je fais:

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(); 
     } 

Mais malheureusement responce je ne reçois que le code source HTML de la page de connexion et il semble que les cookies ne contiennent pas l'ID de session. Toutes les demandes que j'effectue après ce code retournent aussi la source HTML de la page de connexion, donc je peux supposer qu'il ne se connecte pas correctement.

Quelqu'un peut-il m'aider à résoudre ce problème ou donner un exemple de travail?


La principale chose que je veux atteindre est la recherche de nouvelles images dans le plugin Nextgen Gallery pour Wordpress. Y a-t-il une façon XML-RPC de le faire?

Merci d'avance.

Répondre

1

Merci à tous. J'ai réussi à le faire fonctionner uniquement en utilisant des sockets. Wordpress envoie plusieurs en-têtes Set-Cookie mais HttpWebRequest ne gère qu'une seule instance de cet en-tête de sorte que certains cookies sont perdus. Lorsque vous utilisez des sockets, je peux obtenir tous les cookies nécessaires et me connecter au panneau d'administration.

+1

Une partie du code wouldnt être mauvais que d'autres les gens cherchent peut-être aussi une solution (comme moi). C'est le point d'un forum ... – C4u

+0

Alors cruel! pourquoi la solution n'est pas là? –

+0

est la réponse acceptée? pas de code? – DidIReallyWriteThat

1

Je ne vois pas de problème évident avec votre code, désolé. Mais Wordpress a une interface XML-RPC, qui doit être activée dans l'interface d'administration. J'ai écrit des scripts python pour cette interface et cela a fonctionné comme un charme.

0

J'ai essayé avec mon compte WordPress.com (protégé par SSL). J'ai découvert que le moyen le plus simple est d'utiliser les sockets .NET pour obtenir les en-têtes HTTP "Set-Cookie", puis d'analyser les en-têtes des objets Cookie .NET et de les utiliser dans CookieContainer avec les cookies pour HttpWebRequest.

La meilleure façon de travailler avec SSL sur les sockets consiste à implémenter SslStream sur NetworkStream lié à la socket.

Exemple:

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()); 
     } 
    } 

Le code est pas très efficace, mais il illustre le processus de connexion à l'interface d'administration.

Hope it helps :)

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

Je ne sais pas si d'autres trouveront cela utile, mais je viens d'utiliser l'API de WordPress pour vous connecter. J'ai créé un utilisateur (CRON_USR) qui « dans les journaux "la nuit dans le cadre d'un travail cron et fait quelques tâches. Le code est le suivant:

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

Depuis WordPress mettre en œuvre une redirection, laissant la page (redirection) empêche le WebRequest d'obtenir le cookie approprié. Pour obtenir le cookie approprié, il faut empêcher les redirections.

request.AllowAutoRedirect = false; 

d'utiliser le cookie-conatainer pour la connexion.

voir le code suivant: (basé sur un exemple de C# livre de Albahari)

 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 a la meilleure réponse pour moi, mais il manquait quelque chose.

dans son code, Remplace:

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

par

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

suivant pour la demande de futur, vous devrez réutiliser CookieContainer.

0

Pour vous connecter par programme pour WordPress sur un hébergement mutualisé (cPanel), TomerBu's réponse a fait l'affaire pour moi avec un ajout: le UserAgent doit être défini comme suit

... 
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"; 
Questions connexes