

PHP - curl - práca na vzdialenom serveri
Potrebujem sa pripojiť na vzdialený server, odoslať do login formulára prihlasovacie údaje a ďalej na ňom fungovať. Podstatný kód vyzerá takto:
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
POST parametre sú upravené do tvaru:
meno=asd%40asd%2esk&heslo=123456
Keď odošlem požiadavku na vzdialený server a vypýtam si odpoveď, dostanem HTML prihlasovacieho formulára bez chybovej hlášky o zlom hesle. Ak údaje pozmením, hlášku dostanem. Informácia, že som bol presmerovaný je len v headeri požiadavky medzi 3 hlavičkami v riadku Location. Dá sa presmerovanie odhaliť aj "krajším" spôsobom alebo len spracovaním tejto dlhej hlavičky? Zrejme mi curl_getinfo() nepomôže, lebo nič vhodné tam nevidím.
Moja druhá otázka je, že keď mám aktívne prihlásenie na serveri (riešené cez SESSION), ako mám prikázať curl, že používam toto PHPSESSID? Viem o vložení cookie do curl, ale len pomocou súboru, ako ten súbor má vyzerať?
No a ktoré PHPSESSID je to čo potrebujem?
http://xxx/login.phpHTTP/1.1 302 Found
Date: Wed, 14 Dec 2011 20:36:06 GMT
Server: Apache
Set-Cookie: PHPSESSID=9f66772b9ad1b8948b87d85a80ef2bd0; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: PHPSESSID=e101bb81dccee88fd1b5d6cb6735e8c1; path=/
Location: main.php
Content-Length: 0
Connection: close
Content-Type: text/html
HTTP/1.1 302 Found
Date: Wed, 14 Dec 2011 20:36:06 GMT
Server: Apache
Set-Cookie: PHPSESSID=13dd6a8a14fb838003e8e9963bf52c83; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Location: http://xxx/login.php
Content-Length: 0
Connection: close
Content-Type: text/html
HTTP/1.1 200 OK
Date: Wed, 14 Dec 2011 20:36:06 GMT
Server: Apache
Set-Cookie: PHPSESSID=bd6adb3d8049fd5557140cfe2b5d2f5a; path=/
Expires: Sun, 16 Mar 2003 05:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Last-Modified: Wed, 14 Dec 2011 20:36:06 GMT
Cache-Control: post-check=0, pre-check=0
Content-Length: 3544
Connection: close
Content-Type: text/html; charset=UTF-8
Pre úplnosť informácii ešte informácia, že prihlasovací formulár odosielam na login.php a presmeruje ma na main.php a to potrebujem zistiť. Stačí mi testovať na výskyt textu "Location: main.php"?
Prečo ťa zaujíma, ako zistiť, či si bol presmerovaný alebo nie? Veď nastavuješ CURLOPT_FOLLOWLOCATION na true, takže o všetky presmerovania sa stará cURL. Ak chceš zistiť, či si bol presmerovaný, tak to sa dá len rozparsovaním hlavičiek. Pozrieš sa na kód stavu (status code), ktorý musí byť 3xx a na hlavičku Location.
Cookie môžeš vložiť pomocou možnosti CURLOPT_COOKIE (viď. curl_setopt).
Pri viacerých Set-Cookie hlavičkách v jednej odpovedi bude platiť zrejme tá posledná. Keďže máš ale 3 odpovede a v tých ďalších máš len jednu Set-Cookie hlavičku, tak platí tá z poslednej odpovede.
Z tých hlavičiek odpovedí vidno, že server vytvára pri každej požiadavke vždy novú session. To je kvôli tomu, že keď nie je nastavené načítanie hlavičiek zo súboru pomocou CURLOPT_COOKIEFILE, tak cookies sa ani neparsujú z odpovede. Takže zrejme budeš chcieť nastaviť CURLOPT_COOKIEFILE a aj CURLOPT_COOKIEJAR na nejaký dočasný súbor. Ďalšia možnosť je nastaviť CURLOPT_FOLLOWLOCATION na false, parsovať hlavičky a spracovávať ich u teba. Potom už vlastne rozumiem, prečo ťa zaujíma ako zistiť, či si bol presmerovaný.
Formát súboru s cookies je buď netscape-ový alebo priamo v podobe HTTP hlavičiek. Netscape-ový formát je tabelátormi oddelená doména, nejaký TRUE/FALSE flag, cesta obmedzujúca platnosť cookie, TRUE/FALSE pre použitie HTTPS a expirácia v podobe UNIX timestampu. Keď ale budeš používať CURLOPT_COOKIEJAR, tak ťa presný formát nemusí zaujímať.
Budem číslovať, aby to bolo prehľadnejšie:
1. Ak nedám FOLLOW_LOCATION na true, tak dostanem prázdny výstup. Znamená to, že som presmerovaný na main.php a nedostanem žiadny výstup? Lebo to si neviem vysvetliť. FOLLOW_LOCATION som vygooglil a vtedy mi to na výstup aspoň niečo dá (ten html kód formulára), hoci som po správnom prihlásení presmerovaný na main.php, čo vidím len v hlavičke. Takže mi to celkom nie je jasné. Ako teda zistím, že som presmerovaný (správne prihlásenie) bez FOLLOW?
2. curl_setopt som pozeral. Ten parameter som prehliadol v tom dlhom zozname. Budem ho vedieť použiť.
3. A tu mi to nie je jasné. V 1. je "Location" a v ostatných nič. Ktorá je teda prvá? Tá 3. či tá 1.? Aby som sa presnejšie vyjadril, hlavičky sú v poradí od poslednej alebo od prvej? Časová značka je tam len v sekundách, takže to neviem určiť, ale pripadá mi to ako od poslednej po prvú.
4. Môže byť ten dočasný súbor aj prázdny?
5. Takže k tomu asi nič.
1. Áno, odpoveďou je presmerovanie (302 Found). Telo odpovede je prázdne. Že si presmerovaný zistíš podľa kódu odpovede 3xx. Kam si presmerovaný, zistíš podľa hlavičky Location.
3. V 1. je Location a aj v 2. Prvá je 1. 1. je presmerovanie na main.php (lebo ťa to prihlásilo), 2. je presmerovanie na login.php (lebo si neodoslal session cookie) a 3. je zobrazenie login.php.
4. Áno.
Zatiaľ ďakujem. Hádam mám všetky potrebné vedomosti. Ale ešte ma napadla posledná otázka:
4. Ak mu dám prázdny súbor a skúsim to, tak bude všetko v poriadku a nemusím iné nastaviť?
Takže funguje to, aj s prázdnym súborom. Mám ešte otázku, že keď budem pokračovať v práci na serveri, stačí, keď zmením v curl adresu alebo musím inicializovať nový curl, aby sa to nebilo?
Stačí zmeniť adresu.