我正在尝试根据我在Firefox中看到来自Live HTTP标头的内容来模拟对网站的POST。
以下是Firefox插件日志的复制/粘贴:
POST / context?tab =登录HTTP / 1.1
主持人:网站
用户代理: Mozilla / 5.0(X11; U; Linux i686; EN-US; rv:1.9.2.13)Gecko / 20101206 Ubuntu / 10.10(特立独行) Firefox / 3.6.13
接受: text / html的,应用/ XHTML + xml的,应用/ XML; Q = 0.9, / 的; Q = 0.8
Accept-Language:en-us,en; q = 0.5
Accept-Encoding:gzip,deflate
接收字符集: ISO-8859-1,utf-8; Q = 0.7,*; Q = 0.7
保持活力:115
连接: keep-alive
推荐人:referer
Cookie:fontsize = 2; JSESSIONID = 0000pXE_BK7TjZFzEyNHqOKzXz2:-1
内容类型: 应用程序/ x-WWW窗体-urlencoded
内容长度:46
登录ID =密码&安培;密码=密码&安培;登录名=登录
POST后紧接着的响应:
HTTP / 1.1 302找到
位置: 网站/背景?标签= p00689
内容 - 语言:en-US
设置Cookie: JSESSIONID = 0000oaKlIeeDRWkX5YCiJu5v1lM:-1; 路径= /
转移编码: chunked
日期:2011年2月7日星期一 格林威治标准时间14:15:21服务器:WebSphere Application Server / 6.1
到期: 1994年12月1日星期四格林威治标准时间16:00:00 Cache-Control:no-cache =“set-cookie, 设置COOKIE2"
根据我的测试,重定向到
的响应网站/上下文?标签= p00689
表示用户已通过身份验证,一切正常。
然而,当试图通过PHP& cURL,我被重定向到一个页面,通知用户他们的会话已经超时。
以下是代码:
// Provider only likes Firefox
$agent = "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.10 (maverick) Firefox/3.6.13";
ini_set("user_agent", $agent);
// Cookie
$cookie = tempnam("/tmp", "curlcookie");
// Post everything that was posted to me.
$fields = $_POST;
foreach($fields as $key=>$value)
{
$fields_string .= "$key=$value&";
}
$fields_string = substr($fields_string, 0, strlen($fields_string) - 1);
// Custom headers
$headers = array(
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language: en-us,en;q=0.5",
"Accept-Encoding: gzip,deflate",
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7",
"Keep-Alive: 115",
"Connection: keep-alive");
// cURL options
$ch = curl_init("website");
curl_setopt($ch, CURLOPT_REFERER, "referer");
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_MAXREDIRS, 1);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$output = curl_exec($ch);
$header = curl_getinfo($ch);
curl_close($ch);
// Debugging junk
echo nl2br($header["request_header"]);
echo "<br/><br/>Output:<br/><br/>$output";
该脚本的输出如下:
POST / context?tab =登录HTTP / 1.1
User-Agent:User-Agent:Mozilla / 5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13)Gecko / 20101206 Ubuntu / 10.10(特立独行) Firefox / 3.6.13
主持人:网站
Pragma:no-cache
推荐人: 引用者:接受: text / html的,应用/ XHTML + xml的,应用/ XML; Q = 0.9, / 的; Q = 0.8
Accept-Language:en-us,en; q = 0.5
Accept-Encoding:gzip,deflate
接收字符集: ISO-8859-1,utf-8; Q = 0.7,*; Q = 0.7
保持活力:115
连接: 保持活力
内容长度: 46
内容类型: 应用程序/ x-WWW窗体-urlencoded
登录ID =用户名和安培;密码=密码&安培;登录名=登录
输出:
HTTP / 1.1 302
发现
当前位置:网站/上下文选项卡= p00697
内容 - 语言:en-US Set-Cookie:
JSESSIONID = 0000Tl8NL1Hg2dbNv_PEnq-bbvr:-1;
Path = / Set-Cookie:
JSESSIONID = 0000Zue58y1tXg3tt4XjB8exXw6:-1;
Path = / Transfer-Encoding:chunked
日期:星期一,2011年2月7日19:18:20 GMT
服务器:WebSphere Application
Server / 6.1到期:1994年12月1日星期四 格林威治标准时间16:00:00缓存控制:
无缓存=“设置的cookie,
设置COOKIE2"
根据我发布的内容,有什么明显的遗漏吗?我接下来应该尝试什么?这些请求在语义上看起来是一样的;我不确定我做错了什么。
答案 0 :(得分:1)
突出的一点是以下代码行:
$cookie = tempnam("/tmp", "curlcookie");
现在如果无法创建文件,那么tempnam
将返回false,这意味着以下代码行:
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
完全没有设置,你应该将cookie文件保存在与执行脚本相同的目录中。
接下来是:
$fields = $_POST;
foreach($fields as $key=>$value)
{
$fields_string .= "$key=$value&";
}
$fields_string = substr($fields_string, 0, strlen($fields_string) - 1);
您不需要这样做,因为CURLOPT_POSTFIELDS
接受一个数组,所以您应该可以这样做:
curl_setopt($ch, CURLOPT_POSTFIELDS, $_POST);
这将确保正确解析实体。
我还认为您可以删除ini_set
,因为file_get_contents
和fopen
等原生函数都是如此,所以仔细检查一行:
ini_set("user_agent", $agent);
另外,我会检查是否已经从主页面设置了一个cookie,例如index.php,因为该站点可能阻止来自直接带有数据的登录页面的来源的请求。