首页 > 解决方案 > 使用 PHP 和 CSRF 登录 CURL 在本地而不是在线工作

问题描述

我正在尝试使用带有 CSRF 令牌的表单中的 CURL 和 PHP 创建登录操作。

表格位于此地址:https://example.com/account/login表格的操作是指:https://example.com/account/login

如果我从本地服务器到远程地址尝试它,它会完美运行。如果我从远程服务器尝试到相同的地址,它不起作用。我需要检查您的意见吗?

这是我的代码:

//URL of the login form.
define('LOGIN_FORM_URL', 'https://example.com/account/login');

//Login action URL. Sometimes, this is the same URL as the login form.
define('LOGIN_ACTION_URL', 'https://example.com/account/login');

//Initiate cURL.
$this->curl = curl_init(LOGIN_ACTION_URL);

//Tells cURL to return the output once the request has been executed.
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);

//Do we want to follow any redirects?
curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true);

curl_setopt($this->curl, CURLOPT_AUTOREFERER, true);


//Where our cookie details are saved. This is typically required
//for authentication, as the session ID is usually saved in the cookie file.
curl_setopt($this->curl, CURLOPT_COOKIEJAR, COOKIE_FILE);
curl_setopt($this->curl, CURLOPT_COOKIEFILE, COOKIE_FILE);

//Sets the user agent. Some websites will attempt to block bot user agents.
//Hence the reason I gave it a Chrome user agent.
curl_setopt($this->curl, CURLOPT_USERAGENT, USER_AGENT);

//We don't want any HTTPS errors.
curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false);

//Execute the login request.
$resultLogin = curl_exec($this->curl);

$dom = new DomDocument();
    $token = '';
    libxml_use_internal_errors(true);
    $dom->loadHTML($resultLogin);
    $tokens = $dom->getElementsByTagName("input");
    for ($i = 0; $i < $tokens->length; $i++) {
        $meta = $tokens->item($i);
        if ($meta->getAttribute('name') === '_csrf_token')
            $token = $meta->getAttribute('value');
    }

    $postValues = array(
        'username' => $this->username,
        'password' => $this->password,
        'login' => '',
        '_csrf_token' => $token
    );

        //Set the URL that we want to send our POST request to. In this
    //case, it's the action URL of the login form.
    curl_setopt($this->curl, CURLOPT_URL, LOGIN_ACTION_URL);
    curl_setopt($this->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);

    //Tell cURL that we want to carry out a POST request.
    curl_setopt($this->curl, CURLOPT_POST, true);

    //Set our post fields / date (from the array above).
    //curl_setopt($this->curl, CURLOPT_POSTFIELDS, http_build_query($postValues));
    curl_setopt($this->curl, CURLOPT_POSTFIELDS, http_build_query($postValues));

    // Add headers
    curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers);

    //We don't want any HTTPS errors.
    curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false);

    //Where our cookie details are saved. This is typically required
    //for authentication, as the session ID is usually saved in the cookie file.
    curl_setopt($this->curl, CURLOPT_COOKIEJAR, COOKIE_FILE);
    curl_setopt($this->curl, CURLOPT_COOKIEFILE, COOKIE_FILE);

    //Sets the user agent. Some websites will attempt to block bot user agents.
    //Hence the reason I gave it a Chrome user agent.
    curl_setopt($this->curl, CURLOPT_USERAGENT, USER_AGENT);

    //Tells cURL to return the output once the request has been executed.
    curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);

    //Allows us to set the referer header. In this particular case, we are
    //fooling the server into thinking that we were referred by the login form.
    curl_setopt($this->curl, CURLOPT_REFERER, LOGIN_FORM_URL);

    //Do we want to follow any redirects?
    curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true);
    $resultLogin2 = curl_exec($this->curl);

#更新 1

调试后,我从 CURL 执行生成了详细输出。我注意到的第一件事是在我的远程文件上我可以找到这个:

* skipping SSL peer certificate verification

但不在本地文件中。也许这就是它在远程上不起作用的原因?

#更新 2

我在一个文件上打印了这个json_encode(curl_getinfo($this->curl))),我得到了两个不同的结果。这里详细介绍:

LOCAL DEBUG -- {\"url\":\"https:\\/\\/mysite.com\\/account\\/login\",\"content_type\":\"text\\/html; charset=UTF-8\",\"http_code\":403,\"header_size\":685,\"request_size\":1010,\"filetime\":-1,\"ssl_verify_result\":0,\"redirect_count\":0,\"total_time\":0.176508,\"namelookup_time\":0.000194,\"connect_time\":0.000213,\"pretransfer_time\":0.000894,\"size_upload\":112,\"size_download\":42170,\"speed_download\":239602,\"speed_upload\":636,\"download_content_length\":42170,\"upload_content_length\":112,\"starttransfer_time\":0.174651,\"redirect_time\":0,\"redirect_url\":\"\",\"primary_ip\":\"server_ip\",\"certinfo\":[],\"primary_port\":443,\"local_ip\":\"ip_of_my_local_computer\",\"local_port\":53952,\"http_version\":2,\"protocol\":2,\"ssl_verifyresult\":0,\"scheme\":\"HTTPS\",\"appconnect_time_us\":224,\"connect_time_us\":213,\"namelookup_time_us\":194,\"pretransfer_time_us\":894,\"redirect_time_us\":0,\"starttransfer_time_us\":174651,\"total_time_us\":176508}
REMOTE DEBUG -- {\"url\":\"https:\\/\\/mysite.com\\/account\\/login\",\"content_type\":\"text\\/html; charset=UTF-8\",\"http_code\":403,\"header_size\":685,\"request_size\":1010,\"filetime\":-1,\"ssl_verify_result\":0,\"redirect_count\":0,\"total_time\":0.125804,\"namelookup_time\":3.5e-5,\"connect_time\":3.7e-5,\"pretransfer_time\":0.000151,\"size_upload\":112,\"size_download\":42170,\"speed_download\":335203,\"speed_upload\":890,\"download_content_length\":42170,\"upload_content_length\":112,\"starttransfer_time\":0.125545,\"redirect_time\":0,\"redirect_url\":\"\",\"primary_ip\":\"server_ip\",\"certinfo\":[],\"primary_port\":443,\"local_ip\":\"ip_of_my_remote_server\",\"local_port\":39082}

如您所见,第一行(本地服务器)我在行和行中有一些附加信息。

谢谢

标签: phpauthenticationcurlcsrf-token

解决方案


推荐阅读