如何使用 PHP Curl 库登录网站?

How to login on website with PHP Curl library?

我想使用 PHP CURL 库登录 https 上的页面。重新加载此页面。但我做不到。我无法从服务器或本地主机建立连接。

 $username = "pik123@gmail.com";
$password = "Bf*****";
$url = "https://eksisozluk.com/giris";
$cookie= "cookies.txt";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if (curl_errno($ch)) die(curl_error($ch));
$dom = new DomDocument();
$dom->loadHTML($response);
$tokens = $dom->getElementsByTagName("meta");
for ($i = 0; $i < $tokens->length; $i++)
{
    $meta = $tokens->item($i);
    if($meta->getAttribute('name') == 'csrf-token')
    $token = $meta->getAttribute('content');
}
$postinfo = "UserName=".$username."&Password=".$password."&_csrf=".$token;
echo $token; //debug info
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postinfo);
$html = curl_exec($ch);
    print($html);
if (curl_errno($ch)) print curl_error($ch);
    curl_close($ch);

我正在打印一个 cookie。只是给你一个空白sheet。我收到错误消息。

您尝试在获取 cookie 之前发送登录凭据,但该网站要求您在登录之前已经有一个 cookie。此外,该网站使用了一个 CSRF token,您需要在登录之前获取它登录,但你没有。另外,您的用户名和密码需要进行urlencode,但您没有对其进行urlencode,例如@是错误的,它应该是Username=pik123%40gmail.com@ urlencoded是%40),用户名变量也称为 UserName,而不是 Username

首先使用正常的 GET 请求获取登录页面,这将为您提供所需的 cookie 和 CSRF 令牌,

然后解析出CSRF token,用application/x-www-form-urlencoded格式的cookie和CSRF token向登录页面发送POST请求,CSRF为__RequestVerificationToken token 和 UserName 作为用户名(注意这里的 CaPiTaLiZaTiOn,它是 UserName,而不是 Username),Password 作为密码,以及一个看似硬编码的参数称为 ReturnUrl,它只包含 /(urlencoded ofc,即 %2F,例如 ReturnUrl=%2F),您应该登录(您的 cookie 会话现在将登录) ,前提是您有有效的凭据。

带有 hhb_curl library 的示例(负责 cookie 处理和 curl 错误检查,将 curl 错误转换为 RuntimeExceptions):

<?php
declare (strict_types = 1);
require_once('hhb_.inc.php');
$username = "pik123@gmail.com";
$password = "Bf*****";
$hc = new hhb_curl('', true);
// get cookie and csrc token:
$html = $hc->exec('https://eksisozluk.com/giris')->getStdOut();
$domd = @DOMDocument::loadHTML($html);
$xp = new DOMXPath($domd);
// grab the login form (it contains the csrf token, among other things)
$login_form = $xp->query("//form[contains(@action,'/giris')]")->item(0);
$login_parameters = array();
foreach ($login_form->getElementsByTagName("input") as $input) {
    $login_parameters[$input->getAttribute("name")] = $input->getAttribute("value");
}
// the CSRF token is called `__RequestVerificationToken`, and $login_parameters now contains roughly:
// array(
//  '__RequestVerificationToken' => 'qTk2Ik0glfV8W1WckmrVkVXujQE8C1eTqMEe36SP-PPUXDn88GG0XYxif3ZMIVGZH08-MEbbtD7i7Q4ymxuasveDZL-WaHQH22r33fOdsqQ1',
//  'ReturnUrl' => '/',
//  'UserName' => '',
//  'Password' => '',
//  'RememberMe' => 'false',
// );
assert(isset($login_parameters['UserName']));
assert(isset($login_parameters['Password']));
$login_parameters['UserName'] = $username;
$login_parameters['Password'] = $password;
// log in
$html = $hc->setopt_array(array(
    CURLOPT_POST => 1,
    CURLOPT_POSTFIELDS => http_build_query($login_parameters)
))->exec()->getStdOut();
// check for login errors:
$domd = @DOMDocument::loadHTML($html);
$xp = new DOMXPath($domd);
$login_errors = array();
foreach ($xp->query("//*[contains(@class,'validation-error')]") as $login_error) {
    $login_error = trim($login_error->textContent);
    if (!empty($login_error)) {
        $login_errors[] = $login_error;
    }
}
unset($login_error);
if (!empty($login_errors)) {
    throw new \RuntimeException("eksisozluk login errors: " . print_r($login_errors, true));
}

输出:

$ php wtf4.php
PHP Fatal error:  Uncaught RuntimeException: eksisozluk login errors: Array
(
    [0] => captcha'yı yanlış girdiniz.
)
 in /cygdrive/c/projects/misc/wtf4.php:46
Stack trace:
#0 {main}
  thrown in /cygdrive/c/projects/misc/wtf4.php on line 46
  • 因为 pik123@gmail.com / Bf***** 不是有效的登录凭据。