Question

Je dois effectuer une action dans le panneau admin wordpress programme mais ne peut pas gérer comment se connecter à Wordpress en utilisant C # et HttpWebRequest.

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'EFFECTUER après que le code de retour également la source HTML de la page de connexion afin que je puisse supposer qu'il ne connecte pas correctement.

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


La chose principale que je veux réaliser est la numérisation de nouvelles images dans le plugin Wordpress Nextgen Gallery for. Y at-il moyen XML-RPC de le faire?

Merci d'avance.

Était-ce utile?

La solution 3

Merci à tout le monde. J'ai réussi comment le faire fonctionner que lorsque vous utilisez des prises. Wordpress envoie plusieurs Set-Cookie en-têtes, mais gère HttpWebRequest une seule instance de cette tête si des cookies sont perdus. Lorsque vous utilisez les sockets que je peux obtenir tous les cookies nécessaires et connectez-vous au panneau d'administration.

Autres conseils

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

afin d'obtenir le cookie correspondant, il faut éviter les redirections.

request.AllowAutoRedirect = false;

que d'utiliser le cookie-conatainer pour la connexion.

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

        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");

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 « connecte » la nuit dans le cadre d'un travail de cron et fait certaines 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/');
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"];

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

J'ai essayé avec mon compte WordPress.com (protégé par SSL). J'ai découvert que le plus simple est d'utiliser les sockets .NET pour obtenir le en-têtes HTTP « Set-Cookie », puis parse les en-têtes à des objets .NET Cookie et ensuite utiliser pour CookieContainer avec les biscuits pour HttpWebRequest.

facile pour travailler avec SSL sur des sockets est de mettre en œuvre SslStream sur NetworkStream lié à la prise.

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.

it helps:)

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 !!!
    }

Suivantes demande de futur, vous devrez réutiliser CookieContainer.

réponse TomerBu fonctionne pour moi avec les ajouts suivants. Je devais installer un certificat SSL sur le site, ajouter le support pour TLS1.2 et définir le UserAgent pour que cela fonctionne. Sans TLS1.2, le serveur Web a immédiatement rejeté ma demande de connexion. Sans le certificat SSL, le site WordPress n'a pas considéré mon C # bot être identifié pour WebRequests ultérieures (même si la connexion a réussi).

*** Remarque importante sur TLS: Je suis un novice de protocole de sécurité et je ne fournirai ce qui a fonctionné pour moi. J'ai installé le .NET 4.7.2 Pack Developer et changé le cadre cible pour mon projet C # .NET à 4.7.2, mais je encore besoin de modifier le ServicePointManager.SecurityProtocol comme indiqué ci-dessous. Recherche pour trouver les meilleures pratiques, y compris la mise à jour .NET et en spécifiant plusieurs versions TLS dans un communiqué de ORed au niveau du bit.

// Add support for TLS 1.2 (note bitwise OR)
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;

...
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";
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top