سؤال

أحتاج إلى أداء بعض الإجراءات في لوحة المسؤول WordPress برمجيا ولكن لا يمكنني إدارة كيفية تسجيل الدخول إلى WordPress باستخدام C # و HttpWebRequest.

إليك ما أقوم به:

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

ولكن لسوء الحظ، أحصل على رمز تسجيل الدخول المصدر HTML فقط، ويبدو أن ملفات تعريف الارتباط لا تحتوي على معرف الجلسة. جميع الطلبات التي أؤديها بعد هذا التعليمات البرمجية أيضا إرجاع مصدر HTML لصفحة تسجيل الدخول حتى أتمكن من افتراض أنها لا تسجيل الدخول بشكل صحيح.

هل يمكن لأي شخص أن يساعدني في حل هذه المشكلة أو مثال على العمل؟


الشيء الرئيسي الذي أريد تحقيقه هو مسح لصور جديدة في البرنامج المساعد NextGen Gallery ل WordPress. هل هناك طريقة XML-RPC للقيام بذلك؟

شكرا مقدما.

هل كانت مفيدة؟

المحلول 3

الشكر للجميع. لقد قمت بإدارة كيفية عملها فقط عند استخدام المقابس. وورد برسل عدة تعيين كوكي رؤوس ولكن HttpWebRequest يتعامل مع مثيل واحد فقط من هذا الرأس حتى يتم فقد بعض ملفات تعريف الارتباط. عند استخدام Sockets، يمكنني الحصول على جميع ملفات تعريف الارتباط اللازمة وتسجيل الدخول إلى لوحة المسؤول.

نصائح أخرى

نظرا لأن WordPress تنفيذ إعادة توجيه، فإن ترك الصفحة (إعادة التوجيه) يمنع webrequest من الحصول على ملف تعريف الارتباط المناسب.

من أجل الحصول على ملف تعريف الارتباط ذي الصلة، يجب أن يمنع المرء إعادة التوجيه.

request.AllowAutoRedirect = false;

من استخدام ملف تعريف الارتباط conatainer لتسجيل الدخول.

راجع التعليمات البرمجية التالية: (بناء على مثال من كتاب Albahari's 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");

لا أعرف إذا سيجد الآخرون هذا مفيدا، لكنني استخدمت للتو API WordPress لتسجيل الدخول. قمت بإنشاء مستخدم (Cron_USR) الذي "يسجل" في الليل كجزء من وظيفة Cron ويقوم ببعض المهام. الرمز هو هذا:

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

لا أرى مشكلة واضحة مع الكود الخاص بك، آسف. ولكن WordPress لديه واجهة XML-RPC، والتي يجب تمكينها في واجهة المسؤول. كتبت بعض البرامج النصية لبثون لهذه الواجهة وعملت مثل سحر.

حاولت هذا مع حساب WordPress.com الخاص بي (محمي مع SSL). لقد اكتشفت أن أسهل طريقة هي استخدام مقابس .NET للحصول على رؤوس HTTP "تعيين ملف تعريف الارتباط"، ثم تحليل الرؤوس إلى كائنات ملف تعريف الارتباط.

أسهل طريقة للعمل مع SSL على مآخذ مآخذ هي تطبيق SSLStream على الشبكة المنتصلة إلى المقبس.

مثال:

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

الكود غير فعال للغاية، لكنه يوضح عملية تسجيل الدخول إلى واجهة الإدارة.

آمل أن يساعد :)

Tomerbu لديه أفضل إجابة بالنسبة لي، ولكن كان هناك شيء مفقود.

في كوده، مدة المبعدة:

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

بواسطة

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

بعد ذلك لطلب فوتور، سيكون عليك إعادة استخدام Cookiecontainer.

توميربو الإجابة يعمل بالنسبة لي مع الإضافات التالية. اضطررت إلى تثبيت شهادة SSL على الموقع الإلكتروني، إضافة دعم TLS1.2 وتعيين UserAgent من أجل العمل لهذا العمل. بدون TLS1.2، رفض WebServer على الفور طلب الاتصال الخاص بي. بدون CERT SSL، لم يفكر موقع WordPress بتسجيل بوت C # بتسجيله للحصول على WebRequests اللاحق (على الرغم من أن تسجيل الدخول كان ناجحا).

*** ملاحظة مهمة حول TLS: أنا مبتدئ بروتوكول أمني وأنا فقط توفير ما كان يعمل بالنسبة لي. لقد قمت بتثبيت حزمة المطور .NET 4.7.2 وتغيير الإطار المستهدف لمشروعي C # إلى .NET 4.7.2، لكنني ما زلت بحاجة إلى تعديل ServicePointMoinager.SecurityProtocol كما هو موضح أدناه. ابحث للعثور على أفضل الممارسات بما في ذلك تحديث .NET وتحديد إصدارات TLS متعددة في عبارة Ored Orded.

// 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";
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top