使用PHP和PHP模拟POST卷曲 [英] Simulating a POST with PHP & cURL
问题描述
我试图根据我在Firefox中的Live HTTP标头看到的内容来模拟对网站的POST。这里是日志的复制/粘贴来自Firefox插件:
POST / context?tab = login HTTP / 1.1
Host:website
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 advertisers接受:
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
连接:
keep-alive employ referer 0047
Cookie:fontsize = 2;
JSESSIONID = 0000pXE_BK7TjZFzEyNHqOKzXz2:-1
Content-Type:
application / x-www-form-urlencodedã
Content-Length:46
loginid = password& password = password& login = Login
POST后:
HTTP / 1.1 302找到的位置:
网站/上下文?tab = p00689
Content-Language:en-USÚ
Set-Cookie:
JSESSIONID = 0000oaKlIeeDRWkX5YCiJu5v1lM:-1;
Path = / cybo Transfer-Encoding:
chunked└Date:Mon,07 Feb 2011
14:15:21 GMTogle Server:WebSphere
Application Server / 6.1 royalty Expires:
Thu,01 Dec 1994 16:00:00 GMT cybo
Cache-Control:no-cache =set-cookie,
set-cookie2
根据我的测试,回应会重新导向至
网站/上下文?tab = p00689
身份验证,一切正常。
但是,当尝试通过PHP& cURL,我被重定向到一个页面,通知用户他们的会话已超时。
以下是代码:
//提供者只喜欢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);
//发布给我的所有内容。
$ fields = $ _POST;
foreach($ fields as $ key => $ value)
{
$ fields_string。=$ key = $ value&;
}
$ fields_string = substr($ fields_string,0,strlen($ fields_string) - 1);
//自定义标题
$ headers = array(
Accept:text / html,application / xhtml + xml,application / xml; q = 0.9,* / *; Accept-Encoding:gzip,deflate,
Accept-Charset:ISO-qs =q = 0.8,
Accept-Language:en-us,en; q = 0.5 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);
//调试垃圾
echo nl2br($ header [request_header]);
echo< br />< br />输出:< br />< br /> $ output
该脚本的输出如下:
POST / context?tab = login 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(maverick)
Firefox / 3.6.13
主机:网站_ $ b pragma:no-cache royalty Referer:
refererpris接受:
text / html,application / xhtml + xml,application / xml; q = 0.9, ; q = 0.8
¥b $ b Accept-Language:en-us,en; q = 0.5
接受编码:gzip,deflate
Accept-Charset:
ISO-8859-1,utf-8; q = 0.7,*; q = 0.7
Keep-Alive:115
连接:
keep-alive employ Content-Length:
46
内容类型:
application / x-www-form-urlencoded
loginid = username& password = password& login = Login
输出:
$ $ $
$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ />
JSESSIONID = 0000Tl8NL1Hg2dbNv_PEnq-bbvr:-1;
Path = / Set-Cookie:0047
JSESSIONID = 0000Zue58y1tXg3tt4XjB8exXw6:-1;
Path = / Transfer-Encoding:chunked
Date:Mon,2011年2月7日19:18:20 GMT
服务器:WebSphereApplication├
Server / 6.1 Expires:Thu,01 Dec 1994 ado
16:00:00 GMT Cache-Control:
no-cache =set-cookie, >
set-cookie2
根据我发布的内容,缺少?我应该尝试下一步?请求看起来在语义上是一样的;我不知道我可以做什么不正确。
显而易见的一件事是下面这行代码:
$ 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
streams等,所以请仔细检查行:
ini_set(user_agent ,$ agent);
此外,我会检查是否有一个已经从主页设置的cookie,如索引.php作为网站可能会阻止来自直接来到具有数据的登录页面的源的请求。
I'm trying to simulate a POST to a website based on what I see coming from Live HTTP headers in Firefox.
Here's a copy/paste of the log from the Firefox plugin:
POST /context?tab=login HTTP/1.1
Host: website
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
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
Referer: referer
Cookie: fontsize=2; JSESSIONID=0000pXE_BK7TjZFzEyNHqOKzXz2:-1
Content-Type: application/x-www-form-urlencoded
Content-Length: 46
loginid=password&password=password&login=Login
And the response that follows immediately after the POST:
HTTP/1.1 302 Found
Location: website/context?tab=p00689
Content-Language: en-US
Set-Cookie: JSESSIONID=0000oaKlIeeDRWkX5YCiJu5v1lM:-1; Path=/
Transfer-Encoding: chunked
Date: Mon, 07 Feb 2011 14:15:21 GMT
Server: WebSphere Application Server/6.1
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Cache-Control: no-cache="set-cookie, set-cookie2"
Based on my testing, a response that redirects to
website/context?tab=p00689
Means that the user was authenticated and everything worked properly.
However, when trying to accomplish this via PHP & cURL, I'm being redirected to a page that informs the user that their session has timed out.
Here's the code:
// 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";
The output from that script is as follows:
POST /context?tab=login 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 (maverick) Firefox/3.6.13
Host: website
Pragma: no-cache
Referer: referer
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
Content-Length: 46
Content-Type: application/x-www-form-urlencoded
loginid=username&password=password&login=Login
Output:
HTTP/1.1 302
Found
Location:website/context?tab=p00697
Content-Language: en-US Set-Cookie:
JSESSIONID=0000Tl8NL1Hg2dbNv_PEnq-bbvr:-1;
Path=/ Set-Cookie:
JSESSIONID=0000Zue58y1tXg3tt4XjB8exXw6:-1;
Path=/ Transfer-Encoding: chunked
Date: Mon, 07 Feb 2011 19:18:20 GMT
Server: WebSphere Application
Server/6.1 Expires: Thu, 01 Dec 1994
16:00:00 GMT Cache-Control:
no-cache="set-cookie,
set-cookie2"
Based on what I've posted, is there anything obvious that I'm missing? What should I try next? The requests look semantically the same; I'm not sure what I could be doing incorrectly.
The one thing that stands out is the following line of code:
$cookie = tempnam("/tmp", "curlcookie");
Now if this fails to create the file then tempnam
would return false, meaning that the following lines of code:
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie);
are as good as not being set at all, you should keep the cookie file within the same directory as the executing script.
the next thing is:
$fields = $_POST;
foreach($fields as $key=>$value)
{
$fields_string .= "$key=$value&";
}
$fields_string = substr($fields_string, 0, strlen($fields_string) - 1);
You do not need to do this as CURLOPT_POSTFIELDS
accepts an array so you should be able to do:
curl_setopt($ch, CURLOPT_POSTFIELDS, $_POST);
This will make sure that the entities are correctly parsed.
I also think you can remove the ini_set
as that's for native functions such as file_get_contents
and fopen
streams etc, so double check the line:
ini_set("user_agent", $agent);
Also I would check to see if there is a cookie already set from the main page, such as index.php as the site may block requests from sources that have come directly to the login page with data.
这篇关于使用PHP和PHP模拟POST卷曲的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!