I need to perform some action in wordpress admin panel programmatically but can’t manage how to login to WordPress using C# and HttpWebRequest.
Here is what I do:
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 += "rn";
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();
}
But unfortunately in responce I get only HTML source code of login page and it seems that cookies don’t contain session ID. All requests which I perform after that code also return HTML source of login page so I can assume that it does not login correctly.
Can anybody help me to solve that problem or give working example?
Main thing which I want to achieve is scanning for new images in Nextgen Gallery plugin for WordPress. Is there XML-RPC way of doing that?
Thanks in advance.
Since WordPress implement a redirect, leaving the page (redirecting) prevents the webrequest from getting the proper cookie.
in order to get the relevant cookie, one must prevent redirects.
than use the cookie-conatainer for login.
see the following code:
(based on an example from Albahari’s C# book)
I don’t know if others will find this helpful, but I just used the WordPress API to log in. I created a user (CRON_USR) who “logs in” at night as part of a cron job and does some tasks.
The code is this:
Thanks to everyone. I managed how to make it work only when using sockets. WordPress sends several Set-Cookie headers but
HttpWebRequest
handles only one instance of such header so some cookies are lost. When using sockets I can get all needed cookies and login to admin panel.TomerBu’s answer works for me with the following additions. I had to install an SSL certificate on the website, add support for TLS1.2 and set the UserAgent in order for this to work. Without TLS1.2, the webserver immediately rejected my connection request. Without the SSL cert, the WordPress site did not consider my C# bot to be logged in for subsequent WebRequests (even though the login was successful).
*** Important note about TLS: I’m a security protocol novice and am only providing what worked for me. I installed the .NET 4.7.2 Developer Pack and changed the target framework for my C# Project to .NET 4.7.2, but I still needed to modify the ServicePointManager.SecurityProtocol as shown below. Search to find best practices including updating .NET and specifying multiple TLS versions in a bitwise ORed statement.
I see no obvious problem with your code, sorry. But WordPress has an XML-RPC interface, which has to be enabled in the admin interface. I wrote some python scripts for this interface and it worked like a charm.
I tried this with my WordPress.com account (protected with SSL). I discovered that the easiest way is to use .NET sockets to get the HTTP “Set-Cookie” headers, then parse the headers to .NET Cookie objects and then use to CookieContainer with the cookies for HttpWebRequest.
Easiest way to work with SSL over sockets is to implement SslStream over NetworkStream bound to the socket.
Example:
The code is not very efficient, but it illustrates the process of logging into the administration interface.
Hope it helps 🙂
TomerBu has the best answer for me, but something was missing.
in his code, remplace :
by
Next for futur request, you’ll have to reuse CookieContainer.