[英]PHP: send request post login web site
我有這個 POST 請求來登錄一個網站:
http://xxxx.net-kont.it/
POST / HTTP/1.1
Host: xxxx.net-kont.it
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: */*
Accept-Language: it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Referer: http://xxxx.net-kont.it/
Content-Length: 1904
Cookie: ASP.NET_SessionId=s44bymd3lm4dsykvymjljv5s
Connection: keep-alive
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
Set-Cookie: SSOAuth=EDCCFF8CD40064D70B3377CD0389FF7F807F0B774F2CE1CA6C015314911D3D69AB819EAB9938C14608842D25991D11D8F1A5A94090DB926BD7001C526B1920A51AC986182EB016C323983716720E8F345B54E02E44C65753E9183843D23F569EF3FE52C03FC8567E809A77387B8C; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Sun, 22 Oct 2017 12:26:40 GMT
Content-Length: 714
----------------------------------------------------------
http://xxxx.net-kont.it/aspx/Empty.aspx?ControllaRichieste=true&CheckCode=29a29a891a7d4d7773f480064e5c869929bcca40e7c84812111f9affbc3be4628a3b7defe8fb9b14f9911be9c6545e7cd31c2fc04b79a8d1e7280e0277264bdcec7428037a43961c3dda5bbd54a2e7ae&wsid=1a57f5e6-bf68-4f2f-9a71-c43e8e8bfbaf&wsnew=false
GET /aspx/Empty.aspx?ControllaRichieste=true&CheckCode=29a29a891a7d4d7773f480064e5c869929bcca40e7c84812111f9affbc3be4628a3b7defe8fb9b14f9911be9c6545e7cd31c2fc04b79a8d1e7280e0277264bdcec7428037a43961c3dda5bbd54a2e7ae&wsid=1a57f5e6-bf68-4f2f-9a71-c43e8e8bfbaf&wsnew=false HTTP/1.1
Host: xxxx.net-kont.it
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://xxxx.net-kont.it/
Cookie: ASP.NET_SessionId=s44bymd3lm4dsykvymjljv5s; SSOAuth=EDCCFF8CD40064D70B3377CD0389FF7F807F0B774F2CE1CA6C015314911D3D69AB819EAB9938C14608842D25991D11D8F1A5A94090DB926BD7001C526B1920A51AC986182EB016C323983716720E8F345B54E02E44C65753E9183843D23F569EF3FE52C03FC8567E809A77387B8C
Connection: keep-alive
Upgrade-Insecure-Requests: 1
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Sun, 22 Oct 2017 12:26:40 GMT
Content-Length: 95935
----------------------------------------------------------
post請求頭需要以下字段:
'__LASTFOCUS' => '',
'__EVENTTARGET' => '',
'__EVENTARGUMENT' => '',
'__VIEWSTATE' => $viewstate,
'__VIEWSTATEGENERATOR' => $viewstategenerator,
'ctl00$hwsid' => $hwsid,
'ctl00$PageSessionId' => $pagesessionid,
'ctl00$DefaultUrl' => $defaulturl,
'ctl00$GenericErrorUrl' => $genericerrorurl,
'ctl00$PopupElement' => '',
'ctl00$PollingTimeoutSecs' => $pollingtimeoutsecs,
'ctl00$bodyContent$txtUser' => $user,
'ctl00$bodyContent$txtPassword' => $password,
'__CALLBACKID' => '__Page',
'__CALLBACKPARAM' => '"hwsid="'.$hwsid.'"&PageSessionId="'.$pagesessionid.'"&DefaultUrl="'.$defaulturl.'"&GenericErrorUrl="'.$genericerrorurl.'"&PopupElement="'.'"&PollingTimeoutSecs="'.$pollingtimeoutsecs.'"&txtUser="'.$user.'"&txtPassword="'.$password,
'__EVENTVALIDATION' => $eventvalidation
通過對 post 請求的分析,您注意到通過發送從網站“ASP.NET_SessionId=”獲取的第一個 cookie,您立即獲得了一個額外的身份驗證 cookie“SSOAuth=”我如何才能獲得第二個 cookie“SSOAuth=”我可以訪問該網站嗎? 我試過這個代碼:
$user = "xx";
$password = "xx";
$url = 'http://xxx.it/Default.aspx';
$contents = file_get_contents($url);
$dom = new DOMDocument;
$dom->loadHTML($contents);
$xpath = new DOMXpath($dom);
$eventvalidation = $xpath->query('//*[@name="__EVENTVALIDATION"]')->item(0)->getAttribute('value');
$viewstate = $xpath->query('//*[@name="__VIEWSTATE"]')->item(0)->getAttribute('value');
$viewstategenerator = $xpath->query('//*[@name="__VIEWSTATEGENERATOR"]')->item(0)->getAttribute('value');
$hwsid = $xpath->query('//*[@name="ctl00$hwsid"]')->item(0)->getAttribute('value');
$pagesessionid = $xpath->query('//*[@name="ctl00$PageSessionId"]')->item(0)->getAttribute('value');
$defaulturl = $xpath->query('//*[@name="ctl00$DefaultUrl"]')->item(0)->getAttribute('value');
$genericerrorurl = $xpath->query('//*[@name="ctl00$GenericErrorUrl"]')->item(0)->getAttribute('value');
$pollingtimeoutsecs = $xpath->query('//*[@name="ctl00$PollingTimeoutSecs"]')->item(0)->getAttribute('value');
$cookies = array_filter(
$http_response_header,
function($v) {return strpos($v, "Set-Cookie:") === 0;}
);
$headers = [
"Accept-language: it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3",
"Content-Type: application/x-www-form-urlencoded; charset=utf-8",
"User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0",
];
foreach ($cookies as $cookie) {
$headers[] = preg_replace("/^Set-/", "", $cookie);
}
$request = array(
'http' => array(
'method' => 'POST',
'timeout' => 0,
'header'=> $headers,
'content' => http_build_query(array(
'__LASTFOCUS' => '',
'__EVENTTARGET' => '',
'__EVENTARGUMENT' => '',
'__VIEWSTATE' => $viewstate,
'__VIEWSTATEGENERATOR' => $viewstategenerator,
'ctl00$hwsid' => $hwsid,
'ctl00$PageSessionId' => $pagesessionid,
'ctl00$DefaultUrl' => $defaulturl,
'ctl00$GenericErrorUrl' => $genericerrorurl,
'ctl00$PopupElement' => '',
'ctl00$PollingTimeoutSecs' => $pollingtimeoutsecs,
'ctl00$bodyContent$txtUser' => $user,
'ctl00$bodyContent$txtPassword' => $password,
'__CALLBACKID' => '__Page',
'__CALLBACKPARAM' => '"hwsid="'.$hwsid.'"&PageSessionId="'.$pagesessionid.'"&DefaultUrl="'.$defaulturl.'"&GenericErrorUrl="'.$genericerrorurl.'"&PopupElement="'.'"&PollingTimeoutSecs="'.$pollingtimeoutsecs.'"&txtUser="'.$user.'"&txtPassword="'.$password,
'__EVENTVALIDATION' => $eventvalidation,
'ctl00$bodyContent$btnLogin' => 'Conferma'
)),
)
);
echo "<hr/>";
$context = stream_context_create($request);
$data = file_get_contents($url, false, $context);
echo htmlentities($data);
但是我得到以下“身份驗證失敗”的輸出:
<Notification><Error Code="" Alert="True" ClosePopup="True" Fatal="False" Message="Autenticazione fallita." /></Notification>
會話將在 HTTP 標頭中,而 file_get_contents 僅獲取 HTTP 正文,因此您將丟失發送 cookie 的“元數據”。
我真的建議使用比這更高級的東西。 @Tarun Lalwani 建議您卷曲。 Curl 可以實現這一點,盡管我更喜歡使用更直觀的東西 Guzzle http://docs.guzzlephp.org/en/stable/ 。
Guzzle 使用 PSR-7 http://www.php-fig.org/psr/psr-7/
這是一個 Guzzle 使用示例,您可以在其中看到訪問標頭是多么容易:
$client = new GuzzleHttp\Client();
$res = $client->request('GET', 'https://api.github.com/user', [
'auth' => ['user', 'pass']
]);
echo $res->getStatusCode();
// "200"
echo $res->getHeader('content-type');
// 'application/json; charset=utf8'
echo $res->getBody();
// {"type":"User"...'
我已經解決了! 比預期的要容易....在這里我只需要刪除引號“:
'__CALLBACKPARAM' => '"hwsid="'.$hwsid.'"&PageSessionId="'.$pagesessionid.'"&DefaultUrl="'.$defaulturl.'"&GenericErrorUrl="'.$genericerrorurl.'"&PopupElement="'.'"&PollingTimeoutSecs="'.$pollingtimeoutsecs.'"&txtUser="'.$user.'"&txtPassword="'.$password,
轉換為:
'__CALLBACKPARAM' => 'hwsid='.$hwsid.'&PageSessionId='.$pagesessionid.'&DefaultUrl='.$defaulturl.'&GenericErrorUrl='.$genericerrorurl.'&PopupElement='.'&PollingTimeoutSecs='.$pollingtimeoutsecs.'&txtUser='.$user.'&txtPassword='.$password,
看起來您正在嘗試直接從網站解析數據,您是否考慮過與網站所有者聯系以構建 API? 無論如何,我推薦使用phantomjs,這樣scraper代碼更簡單,流量等JS對策也更容易解決。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.