php - 使用 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}
如您所见,第一行(本地服务器)我在行和行中有一些附加信息。
谢谢
解决方案
推荐阅读
- r - 在最近的 blogdown 更新后,无法将新的 .Rmd 文件呈现为 html
- c++ - 如何在do while循环中输出正的最小数字?
- c++ - 在 C++ 中放置一个负索引
- python - 为什么这个递归函数会输出多个结果/可能性?这是数独解谜程序代码的一部分
- java - 等于与内存比较问题
- python - xlsxwriter 布隆伯格公式
- javascript - 如何使折叠卡内的列表水平
- ios - SwiftUI:获取数据并传递给子视图的最佳方法?
- reactjs - useMemo on useState 与 Array 和许多 Object
- java - Java函数在调用两次时不起作用