Cookies文件未从远程站点生成PHP和cURL登录

Cookies文件未从远程站点生成PHP和cURL登录,php,curl,Php,Curl,根据下面的代码,我没有成功登录到$loginUrl(即没有在与文件相同的目录中生成cookie.txt文件),因此无法从$url加载HTML数据(即没有加载回音)。当我查看loginUrl的curl\u exec时,它似乎没有向表单提交用户名和密码,尽管我有$store=curl\u exec($ch),因为表单显示而不是成功登录 function parseDOM($data) { global $projectID, $sRedirect, $database; libxml_use

根据下面的代码,我没有成功登录到$loginUrl(即没有在与文件相同的目录中生成cookie.txt文件),因此无法从$url加载HTML数据(即没有加载回音)。当我查看loginUrl的curl\u exec时,它似乎没有向表单提交用户名和密码,尽管我有$store=curl\u 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);

}

以下是我将使用的方法。首先,使用Google Chrome并打开网络检查器。如果您随后手动登录,那么您将能够看到发送的所有请求头、表单字段等

有了这些信息,您可以构造一个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\u init()
向第二个URL发出第二个请求,并包括
CURLOPT\u COOKIEFILE
CURLOPT\u COOKIEJAR
参数


希望这能给你一些工作的依据。祝你好运。

你没有告诉我们你想在哪里登录,但在一条评论中,你发布了这个链接
https://auth.lib.unc.edu/ezproxy_auth.php?url=https://global.factiva.com/ha/default.aspx
,它本身链接到4个不同的登录页面。但是,您在评论中发布的详细日志表明您正在尝试登录名为
Onyen
的网站。在做了一些研究之后,发现他们有一个非常奇怪的登录系统,它从-向该url发出GET请求开始,这将创建一个cookie会话,您将需要该会话来处理所有后续请求,并在HTML中为您提供所需的信息。解析出HTML
表单的URL是什么?我想亲自查看并检查表单字段名称、隐藏字段等感谢您的帮助。loginURL的URL是你需要的吗?如果我去loginURL,我会看到我需要看到包含用户名和密码字段的登录页面。你是对的。例如,如果您转到,则可以单击Onyen登录按钮,这将带您进入登录页面。正如我之前多次说过的,无论何时调试CURL请求,启用
CURLOPT\u VERBOSE
您都不会对用户名/密码进行URL编码,因此,如果用户名或密码包含空格或
&
或ÆØØ或一组其他字符,则无法工作,服务器接收到错误的用户名/密码。其次,不要手动发送内容长度标题,curl会为您这样做,与您不同的是,curl不会搞砸并发送错误的号码。第三,不要手动设置主机头,curl也会为您这样做。第四,不要手动设置用户代理头,而要设置CURLOPT_USERAGENT,这可以确保如果curl遵循“位置”-http重定向,用户代理将保留在每个请求上。第五,如果使用
应用程序/x-www-form-urlencoded
多部分/表单数据
编码,不要手动设置
内容类型
头,curl将自动检测您使用的编码,并设置适当的标题,与您不同的是,这样做不会有任何打字错误,先生,您正在使用
application/x-www-form-urlencoded
-encoding。第六,为什么要伪造referer标题?一些网站可以检测到你有一个虚假的参考标题,并阻止你。相反,只需向该页面发出一个普通请求,设置CURLOPT_AUTOREFER,并拥有一个真正的referer头。它的安全代码仍然不工作。此外,代码在loginURL.whereVerbose信息:Single Sign-On UNC Chapel Hill Single Sign-On-Error发生错误:NoSouchFlowExecutionException谢谢!我将尝试一下,当我更新代码并将hhb_u.inc.php文件放在同一个文件中时,我会得到一个HTTP错误500directory@JustinWilsonphp错误日志说什么?@JustinWilson(如果您不知道错误日志在哪里,常见的位置包括
/var/log/apache2/error.log
/var/log/nginx/error.log
,否则,它可能由php.ini中的error\u log指令定义-默认情况下,它只将其发送到web服务器(通常是Apache或nginx),web服务器将其发送到自己的错误日志)@JustinWilson噢,这段代码是用PHP7编写的,如果您尝试在PHP5中运行它,您会得到错误。不过,如果您删除输入类型声明,并返回类型声明,并用
hhb_uuuuuu.inc.php
替换
hhb_uuuu.inc.PHP5.php
<?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 () );