代码之家  ›  专栏  ›  技术社区  ›  T-Rex

如何以编程方式登录WordPress?

  •  7
  • T-Rex  · 技术社区  · 16 年前

    我需要以编程方式在WordPress管理面板中执行一些操作,但无法管理如何使用c和httpWebRequest登录WordPress。

    我要做的是:

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

    但不幸的是,在responce中,我只得到了登录页面的HTML源代码,而cookie似乎不包含会话ID。在该代码之后执行的所有请求也返回了登录页面的HTML源代码,因此我可以假定它没有正确登录。

    有人能帮我解决这个问题吗?或者举个例子?


    我要实现的主要目标是在WordPress的NextGenGallery插件中扫描新图像。有XML-RPC的方法吗?

    事先谢谢。

    8 回复  |  直到 8 年前
        1
  •  7
  •   TomerBu    13 年前

    由于WordPress实现了重定向,离开页面(重定向)会阻止WebRequest获取正确的cookie。

    为了获得相关的cookie,必须防止重定向。

    request.AllowAutoRedirect = false;
    

    而不是使用cookie conatainer登录。

    请参见以下代码: (以阿尔巴哈里的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");
    
        2
  •  4
  •   Kungfug    15 年前

    我不知道其他人是否会觉得这有帮助,但我只是使用WordPressAPI登录。我创建了一个用户(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/');
    
        3
  •  2
  •   T-Rex    16 年前

    谢谢大家。我设法使它只在使用插座时工作。WordPress发送几个 设置曲奇 报头 HttpWebRequest 只处理此类头的一个实例,因此会丢失一些cookie。使用套接字时,我可以获取所有需要的cookie并登录到管理面板。

        4
  •  2
  •   Mike Koder    16 年前
    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"];
    
        5
  •  1
  •   Achim    16 年前

    对不起,我看不出你的代码有明显的问题。但是WordPress有一个XML-RPC接口,必须在管理接口中启用它。我为这个接口编写了一些python脚本,它的工作方式很吸引人。

        6
  •  0
  •   user292316    16 年前

    我用我的wordpress.com帐户(受SSL保护)尝试了这个方法。我发现最简单的方法是使用.NET套接字获取HTTP“set cookie”头,然后将头解析为.NET cookie对象,然后使用cookie为httpwebrequest生成cookie容器。

    通过套接字使用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());
            }
        }
    

    代码不是很有效,但它说明了登录到管理界面的过程。

    希望有帮助:)

        7
  •  0
  •   Giova    13 年前

    托默布给了我最好的答案,但有些东西不见了。

    在他的代码中,Remplace:

     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。

        8
  •  0
  •   Tony    8 年前

    TomerBu's 这个答案对我有以下补充。我必须在网站上安装一个ssl证书,添加对tls1.2的支持,并设置useragent以使其正常工作。没有tls1.2,Web服务器立即拒绝了我的连接请求。如果没有ssl证书,Wordpress站点不会考虑我的C bot在随后的webrequest中登录(即使登录成功)。

    ***关于tls的重要说明:我是安全协议新手,只提供对我有用的东西。我安装了.NET 4.7.2开发人员包,并将我的C项目的目标框架更改为.NET 4.7.2,但我仍然需要修改servicePointManager.securityProtocol,如下所示。搜索以查找最佳实践,包括更新.NET并在按位或按位运算的语句中指定多个TLS版本。

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