[英]Cookies File Not Generated PHP and cURL Login from Remote Site
我没有成功登录到$ loginUrl(即根据下面的代码在与文件相同的目录中没有生成cookie.txt文件),因此无法从$ url加载HTML数据(即没有加载回声) 。 当我查看loginUrl的curl_exec时,看起来它没有提交表单的用户名和密码,虽然我有$ store = curl_exec($ ch),因为显示的是表单而不是成功登录。
function parseDOM($data)
{
global $projectID, $sRedirect, $database;
libxml_use_internal_errors(true);
$dom = new DOMDocument();
if(!$dom->loadHTML($data))
{
echo "did not load";
}
}
$ch = @curl_init();
if($ch)
{
$username = 'username';
$password = 'password';
//$url = 'https://global-factiva-com.libproxy.lib.unc.edu/ha/default.aspx#./!?&_suid=14977301633480007720669669887936';
//trying different URL
$url = 'https://global.factiva.com.libproxy.lib.unc.edu/redir/default.aspx?P=sa&NS=16&AID=9UNI011500&f=g&an=j000000020010807dw8b00lc2&cat=a';
//loginUrl is the same as the URL for the form post action
$loginUrl = 'https://sso.unc.edu/idp/profile/SAML2/POST/SSO;jsessionid=A2C0B6480084BED37E1104E903B07AA9?execution=e1s1';
//Set the URL to work with
curl_setopt($ch, CURLOPT_URL, $loginUrl);
// ENABLE HTTP POST
curl_setopt($ch, CURLOPT_POST, 1);
//Set the post parameters
curl_setopt($ch, CURLOPT_POSTFIELDS, 'j_username='.$username.'&j_password='.$password);
//Handle cookies for the login
$cookie=dirname(__FILE__)."\\cookie.txt";
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
//execute the request (the login)
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$store = curl_exec($ch);
//now access the URL that requires login
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$content=curl_exec($ch);
$headers = curl_getinfo($ch);
curl_close($ch);
parseDOM($content);
}
这是我将使用的方法。 首先,使用谷歌浏览器并打开网络检查器。 如果您随后手动登录,那么您将能够看到发送的所有请求标头,表单字段等。
有了这些信息,您可以构建一个curl请求并指定所有自定义标头。 在没有合法的引用者或用户代理的情况下拒绝请求之前,我已经使用过系统。
所以,举个例子..
<?php
$username = 'hello';
$password = 'letmein';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"https://sso.unc.edu/idp/profile/SAML2/POST/SSO?execution=e1s1");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS,'j_username:='.$username.'&j_password:='.$password.'&_eventId_proceed:=');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$headers = [
'Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding:gzip, deflate, br',
'Accept-Language:en-US,en;q=0.8,es;q=0.6',
'Cache-Control:max-age=0',
'Connection:keep-alive',
'Content-Length:57',
'Content-Type:application/x-www-form-urlencoded',
'Host:sso.unc.edu',
'Origin:https://sso.unc.edu',
'Referer:https://sso.unc.edu/idp/profile/SAML2/POST/SSO?execution=e1s1',
'Upgrade-Insecure-Requests:1',
'User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$output = curl_exec ($ch);
curl_close ($ch);
echo $output;
?>
一旦你运行它,然后希望你登录并设置cookie。 然后,您可以使用新的curl_init()
向第二个URL发出第二个请求,并包含CURLOPT_COOKIEFILE
和CURLOPT_COOKIEJAR
参数。
希望这能让你有所作为。 祝好运。
你还没有告诉我们你想要登录的地方,但在评论中,你发布了这个链接https://auth.lib.unc.edu/ezproxy_auth.php?url=https://global.factiva.com/ha/default.aspx
,它本身链接到4个不同的登录页面。 但是,您在Cookie文件未生成PHP和cURL登录远程站点的评论中发布的CURLOPT_VERBOSE日志表明您正在尝试登录名为Onyen
的站点。 经过一些研究后,他们发现了一个非常奇怪的登录系统,从https://auth.lib.unc.edu/ezproxy_auth.php?url=https://global.factiva.com/ha/default开始。 aspx - 向该URL发出GET请求,这将创建一个cookie会话,您将需要所有后续请求,并在HTML中提供所需的信息。 解析HTML <form
Onyen
,其中包含value
-property中包含Onyen
的<input
Onyen
(要查找的输入表单,看起来像<input name="submit" value="Onyen Sign In" accesskey="o" type="submit">
),这个表单元素为您提供了3个输入元素,您需要将这些元素添加到下一个GET请求中,您可以从表单的action
属性中获取这些元素。 我怀疑所有的值都是常量,除了1叫做auth
,这可能是每个cookie会话或ip地址或类似的东西所特有的。 从我的浏览器(以及后来的php)生成的URL原来是https://auth.lib.unc.edu/authentication.php?url=https://global.factiva.com/ha/default.aspx&auth=shibboleth&submit=Onyen+Sign+In
- 现在如果您正确地完成了所有操作,生成了正确的URL并使用之前请求中收到的cookie发送它,它应该响应302 Found
http重定向,您必须遵循。 在此重定向之后,您将获得另一个页面,其中包含一个带有单个<form
标签的html,您必须提取其URL,以及<input
必须解析其名称和值的<input
元素,并添加到您的neext POST请求,该请求将转到https://sso.unc.edu/idp/profile/SAML2/POST/SSO
- 现在这个POST提供了一个http 302 Found重定向,你也必须遵循它。 现在关注重定向,你最终得到https://sso.unc.edu/idp/profile/SAML2/POST/SSO?execution=e2s1
,其中有一个带有<form
标签的html,带有<input
元素的名字和你必须解析的值,并填写j_username
和j_password
输入,并添加到你的下一个POST请求,该请求转到https://sso.unc.edu/idp/profile/SAML2/POST/SSO?execution=e2s1
- 现在使用有效的用户名/密码和cookie会话发送POST请求,可能会让您登录。这是一个实现,使用DOMDocument / DOMXpath进行HTML解析,以及来自https://github.com/divinity76/hhb_的 hhb_curl 。 inc.php /斑点/主/ hhb_.inc.php为HTTP /饼干的东西(它的一个libcurl的包装器),只需更换username_here
与真实的用户名,和password_here
与真正的密码,在线路72及73。
<?php
declare(strict_types = 1);
require_once ('hhb_.inc.php');
function getFormUrl(\hhb_curl $hc, \DOMNode $form): string {
$url = $form->getAttribute ( "action" );
if (empty ( $url )) {
$url = '';
}
if (! parse_url ( $url, PHP_URL_HOST )) {
$url = 'https://' . rtrim ( parse_url ( $hc->getinfo ( CURLINFO_EFFECTIVE_URL ), PHP_URL_HOST ), '/' ) . '/' . ltrim ( $url, '/' );
}
if (false === strpos ( $url, '?' )) {
$url .= '?';
}
return $url;
}
$hc = new hhb_curl ( 'https://auth.lib.unc.edu/ezproxy_auth.php?url=https://global.factiva.com/ha/default.aspx', true );
$hc->exec ();
// hhb_var_dump ( $hc->getStdErr (), $hc->getStdOut () );
$domd = @DOMDocument::loadHTML ( $hc->getResponseBody () );
$form = (new DOMXPath ( $domd ))->query ( '//input[contains(@value,\'Onyen Sign In\')]/parent::form' )->item ( 0 );
$url = getFormUrl ( $hc, $form );
// probably looks like $url = 'https://auth.lib.unc.edu/authentication.php?';
$queryparms = array ();
foreach ( $form->getElementsByTagName ( "input" ) as $input ) {
$url .= urlencode ( $input->getAttribute ( "name" ) ) . '=' . urlencode ( $input->getAttribute ( "value" ) ) . '&';
}
$url = substr ( $url, 0, - 1 );
// hhb_var_dump ( $url );
$hc->exec ( $url );
// hhb_var_dump ( $hc->getStdErr (), $hc->getStdOut () );
$domd = @DOMDocument::loadHTML ( $hc->getResponseBody () );
$form = $domd->getElementsByTagName ( "form" )->item ( 0 );
$url = getFormUrl ( $hc, $form );
$posts = array ();
foreach ( $form->getElementsByTagName ( "input" ) as $input ) {
$name = $input->getAttribute ( "name" );
if (empty ( $name )) {
continue;
}
$posts [$name] = $input->getAttribute ( "value" );
}
// hhb_var_dump ( $posts );
$hc->setopt_array ( array (
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query ( $posts ),
CURLOPT_URL => $url
) );
$hc->exec ();
// hhb_var_dump ( $hc->getStdErr (), $hc->getStdOut () );
$domd = @DOMDocument::loadHTML ( $hc->getResponseBody () );
$form = $domd->getElementsByTagName ( "form" )->item ( 0 );
$url = getFormUrl ( $hc, $form );
$posts = array ();
foreach ( $form->getElementsByTagName ( "input" ) as $input ) {
$name = $input->getAttribute ( "name" );
if (empty ( $name )) {
continue;
}
$posts [$name] = $input->getAttribute ( "value" );
}
foreach ( $form->getElementsByTagName ( "button" ) as $button ) {
$name = $button->getAttribute ( "name" );
if (empty ( $name )) {
continue;
}
$posts [$name] = $button->getAttribute ( "value" );
}
assert ( isset ( $posts ['j_username'] ), 'failed to find the username input!' );
assert ( isset ( $posts ['j_password'] ), 'failed to find the password input!' );
$posts ['j_username'] = 'username_here';
$posts ['j_password'] = 'password_here';
hhb_var_dump ( $posts );
$hc->setopt_array ( array (
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query ( $posts ),
CURLOPT_URL => $url
) );
$hc->exec ();
hhb_var_dump ( $hc->getStdErr (), $hc->getStdOut () );
编辑:修复了一个错误,其中<button>
元素的名称没有附加到POST数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.