PHP,cURL 发布以登录 WordPress
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/728274/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP, cURL post to login to WordPress
提问by mmundiff
I am working on a project for a client which needs an automatic login from a link click.
我正在为客户开发一个项目,该项目需要通过单击链接进行自动登录。
I'm using a handshake page to do this with the following code:
我正在使用握手页面通过以下代码执行此操作:
$username = "admin";
$password = "blog";
$url = "http://wordpressblogURL/";
$cookie = "cookie.txt";
$postdata = "log=" . $username . "&pwd=" . $password . "&wp-submit=Log%20In&redirect_to=" . $url . "blog/wordpress/wp-admin/&testcookie=1";
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url . "blog/wordpress/wp-login.php");
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt ($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6");
curl_setopt ($ch, CURLOPT_TIMEOUT, 60);
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 0);
curl_setopt ($ch, CURLOPT_COOKIEJAR, $cookie);
curl_setopt ($ch, CURLOPT_REFERER, $url . "blog/wordpress/wp-login.php");
curl_setopt ($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt ($ch, CURLOPT_POST, 1);
$result = curl_exec ($ch);
curl_close($ch);
echo $result;
exit;
This works fine. It logs me in great.
这工作正常。它让我登录得很好。
The problem is that I believe WordPress keys off of the URL.
问题是我相信 WordPress 密钥关闭了 URL。
To elaborate, my handshake page (which logs me in) is in the "blog" directory and my WordPress application is in the "wordpress" directory which sits inside the "blog" directory. The URL in the browser says ..blog/handshake.php. However, it has the Admin section of WordPress in the browser window. WordPress Admin links now do not function correctly, because the URL is in the ../blogdirectory when it needs to be in the ..blog/wordpress/wp-admindirectory.
详细说明,我的握手页面(让我登录)位于“blog”目录中,而我的 WordPress 应用程序位于位于“blog”目录内的“wordpress”目录中。浏览器中的 URL 为..blog/handshake.php。但是,它在浏览器窗口中有 WordPress 的管理部分。WordPress 管理链接现在无法正常工作,因为 URL 在../blog需要位于目录中时位于..blog/wordpress/wp-admin目录中。
Is there a way in cURLto make it so that the URL in the browser reflects the actual page?
cURL 中是否有一种方法可以使浏览器中的 URL 反映实际页面?
Should I be using FSockOPen instead?
我应该改用 FSockOPen 吗?
采纳答案by Skone
Kalium got this right -- paths in the WordPress interface are relative, causing the administration interface to not work properly when accessed in this manner.
Kalium 做对了——WordPress 界面中的路径是相对的,导致管理界面在以这种方式访问时无法正常工作。
Your approach is concerning in a few ways, so I'd like to make a few quick recommendations.
您的方法在几个方面令人担忧,因此我想提出一些快速建议。
Firstly, I would try to find a way to remove the $usernameand $passwordvariables from being hard-coded. Think about how easy this is to break -- if the password is updated via the administration interface, for instance, the hard-coded value in your code will no longer be correct, and your "auto-login" will now fail. Furthermore, if someone somehow comprises the site and gains access to handshake.php-- well, now they've got the username and password for your blog.
首先,我会尝试找到一种方法来从硬编码中删除$username和$password变量。想想这有多么容易破解——例如,如果密码是通过管理界面更新的,代码中的硬编码值将不再正确,您的“自动登录”现在将失败。此外,如果有人以某种方式组成了该站点并获得了访问权限handshake.php- 那么,现在他们已经获得了您博客的用户名和密码。
It looks like your WordPress installation rests on the same server as the handshake script you've written, given the path to /blogis relative (in your sample code). Accordingly, I'd suggest trying to mimic the session they validate against in your parent applications login. I've done this several times in the past -- just can't recall the specifics. So, for instance, your login script would not only set your login credentials, but also set the session keys required for WordPress authentication.
鉴于路径/blog是相对的(在您的示例代码中),看起来您的 WordPress 安装与您编写的握手脚本位于同一台服务器上。因此,我建议尝试模仿他们在您的父应用程序登录中验证的会话。我过去做过几次——只是不记得具体细节了。因此,例如,您的登录脚本不仅会设置您的登录凭据,还会设置 WordPress 身份验证所需的会话密钥。
This process will involve digging through a lot of WordPress's code, but thats the beauty of open source! Instead of using cURL and hard-coding values, try to simply integrate WordPress's authentication mechanism into your application's login mechanism. I'd start by looking at the source for wp-login.phpand going from there.
这个过程将涉及挖掘大量 WordPress 的代码,但这就是开源的美妙之处!与其使用 cURL 和硬编码值,不如尝试将 WordPress 的身份验证机制简单地集成到应用程序的登录机制中。我会首先查看源头wp-login.php并从那里开始。
If all else fails and you're determined to not try to mesh your session authentication mechanism with that of WordPress, then you could immediately fix your problem (without fixing the more concerning aspects of your approach) with these changes to your code:
如果所有其他方法都失败了,并且您决定不尝试将会话身份验证机制与 WordPress 的会话身份验证机制结合起来,那么您可以通过对代码进行以下更改来立即解决您的问题(无需解决方法中更相关的方面):
First, add the following curl_opt:
首先,添加以下 curl_opt:
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie); // Enables session support
Then, add this after closing the cURL handler:
然后,在关闭 cURL 处理程序后添加:
curl_close($ch);
// Instead of echoing the result, redirect to the administration interface, now that the valid, authenticated session has been established
header('location: blog/wordpress/wp-admin/');
die();
So, in this less than ideal solution you'd use cURL to authenticate the user, and then rather than attempt to hiHyman the administration interface into that current page, redirect them to the regular administration interface.
因此,在这个不太理想的解决方案中,您将使用 cURL 对用户进行身份验证,然后不要尝试将管理界面劫持到当前页面,而是将它们重定向到常规管理界面。
I hope this helps! Let me know if you need more help / the solution isn't clear.
我希望这有帮助!如果您需要更多帮助/解决方案不清楚,请告诉我。
回答by Kalium
Check the HTML source. It sounds like WP's links may be relative. Instead of making this process even more complicated than it already is, however, I suggest you perform the login, hand the user whatever cookies are required, and redirect them.
检查 HTML 源代码。听起来 WP 的链接可能是相对的。然而,与其让这个过程变得比现在更复杂,我建议您执行登录,将需要的任何 cookie 交给用户,然后重定向它们。
Otherwise you're coding a proxy, piece by piece.
否则,您将一个一个地编写代理。
回答by Chris Henry
If your script doesn't perform all the functions you need in a single execution, you may need to parse out the cookie values, store them in a file, and then resend on the next execution. Check out the CURLOPT_COOKIEFILE option.
如果您的脚本在一次执行中没有执行您需要的所有功能,您可能需要解析 cookie 值,将它们存储在一个文件中,然后在下一次执行时重新发送。查看 CURLOPT_COOKIEFILE 选项。
回答by Jake N
Use Zend Framework's Cookiesclass to manage them for you. I have used this in the past for crawling secure sections of a web site using cURL.
使用Zend Framework 的 Cookies类为您管理它们。我过去曾使用它来使用cURL抓取网站的安全部分。
回答by Berty
Here is the code that worked for me:
这是对我有用的代码:
The key change is that I removed the parameter called "testcookie" from my post string.
关键的变化是我从我的帖子字符串中删除了名为“testcookie”的参数。
Note: add your website instead of "mywordpress" and username and password in the below code
注意:在下面的代码中添加您的网站而不是“mywordpress”以及用户名和密码
$curl = curl_init();
//---------------- generic cURL settings start ----------------
$header = array(
"Referer: https://mywordpress/wp-login.php",
"Origin: https://mywordpress",
"Content-Type: application/x-www-form-urlencoded",
"Cache-Control: no-cache",
"Pragma: no-cache",
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Safari/605.1.15"
);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Safari/605.1.15');
curl_setopt($curl, CURLOPT_AUTOREFERER, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_COOKIESESSION, true);
curl_setopt($curl, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_setopt($curl, CURLOPT_COOKIEJAR, 'cookies.txt');
//---------------- generic cURL settings end ----------------
$url = 'https://mywordpress/wp-login.php';
curl_setopt($curl, CURLOPT_URL, $url);
$post = 'log=username&pwd=password&wp-submit=Log+In&redirect_to=https%3A%2F% mywordpress%2Fwp-admin%2F';
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
$output = curl_exec($curl);
curl_close ($curl);
echo ($output)

