2009-08-15 25 views
5

Necesito realizar alguna acción en el panel de administración de WordPress mediante programación, pero no puedo administrar cómo iniciar sesión en Wordpress usando C# y HttpWebRequest.¿Cómo iniciar sesión en wordpress mediante programación?

Aquí es lo que hago:

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

Pero, lamentablemente, en responce recibo único código fuente HTML de la página de inicio de sesión y parece que las cookies no contienen ID de sesión. Todas las solicitudes que realizo después de ese código también devuelven la fuente HTML de la página de inicio de sesión, por lo que puedo suponer que no se inicia correctamente.

¿Alguien me puede ayudar a resolver ese problema o dar un ejemplo de trabajo?


Lo principal que quiero lograr es buscar nuevas imágenes en el plugin Nextgen Gallery para Wordpress. ¿Hay forma XML-RPC de hacer eso?

Gracias de antemano.

Respuesta

1

Gracias a todos. Logré cómo hacerlo funcionar solo cuando uso conectores. Wordpress envía varios Set-Cookie encabezados, pero HttpWebRequest maneja solo una instancia de dicho encabezado por lo que algunas cookies se pierden. Al usar sockets, puedo obtener todas las cookies necesarias e iniciar sesión en el panel de administración.

+1

Parte del código no sería malo como otra las personas quizás también estén buscando una solución (como yo). Ese es el punto de un foro ... – C4u

+0

¡Tan cruel! ¿por qué la solución no está allí? –

+0

esta es la respuesta aceptada? ¿sin código? – DidIReallyWriteThat

1

No veo ningún problema obvio con su código, lo siento. Pero Wordpress tiene una interfaz XML-RPC, que debe habilitarse en la interfaz de administración. Escribí algunos scripts de Python para esta interfaz y funcionó a las mil maravillas.

0

Intenté esto con mi cuenta de WordPress.com (protegida con SSL). Descubrí que la forma más fácil es usar sockets .NET para obtener los encabezados HTTP "Set-Cookie", luego analizar los encabezados de los objetos de Cookie .NET y luego usar CookieContainer con las cookies para HttpWebRequest.

La manera más fácil de trabajar con SSL sobre sockets es implementar SslStream sobre NetworkStream vinculado al socket.

Ejemplo:

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

El código no es muy eficiente, pero ilustra el proceso de iniciar sesión en la interfaz de administración.

espero que ayude :)

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

No sé si otros encontrarán útil esta información, pero acabo de utilizar las API de WordPress que entrar. He creado un usuario (CRON_USR), que "en los registros de "por la noche como parte de un trabajo cron y realiza algunas tareas. El código es el siguiente:

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

Desde WordPress implementar una redirección, salir de la página (redirigir) evita que el WebRequest de conseguir la cookie adecuada.

para obtener la cookie relevante, se deben evitar las redirecciones.

request.AllowAutoRedirect = false; 

que usar el cookie-conatainer para iniciar sesión.

ver el siguiente código: (en base a un ejemplo de C# libro 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 tiene la mejor respuesta para mí, pero algo faltaba.

en su código, remplace:

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

por

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

siguiente para la solicitud de futur, que tendrá que volver a utilizar CookieContainer.

0

Para autenticarse mediante programación para WordPress en un servidor compartido (cPanel), TomerBu's respuesta hizo el truco para mí con un añadido: la UserAgent debe definirse de la siguiente manera

... 
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"; 
Cuestiones relacionadas