curl - 需要用php和curl登录ipb板
问题描述
我正在尝试使用 CURL 和 PHP 登录 IP 板。这是我正在使用的代码。有人有想法吗?
<?php
$url=stream_get_contents(fopen('https://invisioncommunity.com/login/', "rb"));
function get_string_between($string, $start, $end){
$string = ' ' . $string;
$ini = strpos($string, $start);
if ($ini == 0) return '';
$ini += strlen($start);
$len = strpos($string, $end, $ini) - $ini;
return substr($string, $ini, $len);
}
$csrf_key = get_string_between($url, '" value="', '">');
$path = "/root/ctemp";
$postinfo = "csrfKey=".$csrf_key."&auth=____USERNAME_______&password=___PASSWORD____&remember_me=1&_processLogin=usernamepassword&_processLogin=usernamepassword";
$cookie_file_path = $path."/cookie.txt";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_NOBODY, false);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path);
//set the cookie the site has for certain features, this is optional
curl_setopt($ch, CURLOPT_COOKIE, "cookiename=0");
curl_setopt($ch, CURLOPT_USERAGENT,
"Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_REFERER, "https://invisioncommunity.com/login/");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postinfo);
curl_exec($ch);
//page with the content I want to grab
curl_setopt($ch, CURLOPT_URL, "https://invisioncommunity.com/discover/unread/");
//do stuff with the info with DomDocument() etc
$html = curl_exec($ch);
echo $html;
curl_close($ch);
?>
解决方案
是的,您的 csrf 令牌与提供给 stream_get_contents 请求的 cookie 会话相关联,没有该 cookie,您的 csrf 令牌毫无价值,而且您永远不会从 stream_get_contents 中提取 cookie(我认为 stream_get_contents 甚至不支持这样做),重写它与 curl_ api 一起使用,并确保 curl 的 cookie 系统已启用(例如,将 CURLOPT_COOKIEFILE 设置为空字符串,这将启用 libcurl 的 cookie 处理系统)。您的 csrf 提取代码也不可靠,它不会解码 html 实体(例如,如果 csrf 令牌包含一个&
,它将被 html 编码为&
,但您的代码不会转换&
回&
. ),而是使用适当的 HTML 解析器,例如 DOMDocument。您也没有对 csrf_key 进行 urlencode,因此如果它包含特殊字符(如 @,稍后会详细介绍),它可能会再次损坏。使用 urlencode() 或 http_build_query() 正确地对 csrf 密钥、用户名和密码进行 urlencode,因为您也没有对它们进行 urlencoding。您知道@
您的电子邮件中的 必须编码为%40
吗?我敢打赌,当你硬编码你的登录电子邮件时,你只写foo@gmail.com
,你不写foo%40gmail.com
,所以你也必须对它进行 urlencode。
试试这个,使用 http_build_query 编码发布数据,并使用 DOMDocument 解析出 csrf 令牌:
<?php
declare(strict_types = 1);
$ch = curl_init ();
curl_setopt_array ( $ch, array (
CURLOPT_COOKIEFILE => '',
CURLOPT_ENCODING => '',
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_URL => 'https://invisioncommunity.com/login/'
) );
$html = curl_exec ( $ch );
$domd = @DOMDocument::loadHTML ( $html );
$xp = new DOMXPath ( $domd );
curl_setopt_array ( $ch, array (
CURLOPT_URL => 'https://invisioncommunity.com/login/',
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => http_build_query ( array (
'csrfKey' => $xp->query ( '//input[@name="csrfKey"]' )->item ( 0 )->getAttribute ( "value" ),
'auth' => '____USERNAME_______',
'password' => '___PASSWORD____',
'remember_me' => 1,
'_processLogin' => 'usernamepassword'
) )
) );
$html = curl_exec ( $ch );
echo $html;
推荐阅读
- sas - 如何在 PROC REPORT 中垂直堆叠分析变量?
- android - 如何仅监视静态 html 以了解网页中的更改
- c# - C# - 调用 Form.Show() 方法非常慢
- excel - 根据用户窗体自动填充单元格区域
- javascript - 加载javascript而不是解析源
- javascript - 为什么 .NET Framework 不将 javascript 文本日期绑定到 C# DateTime?
- java - 在 Spring Initializr Gradle 项目中启用 Vaadin 流生产模式
- makefile - 关于 Make 的一些基本问题:用图形编制报告
- c - 将双指针传递给 C 和 C++ 中的函数的区别
- java - Java/Swing JButton 不显示其文本并且不执行其操作