środa, 20 maja 2015

[PHP][cURL] Podstawy cz.4 - cookies

TRUE
8097816399849509347
Wysyłanie cookies może odbywać się dwukierunkowo, tj. serwer może w odpowiedzi zażądać utworzenia pliku ciasteczka w przeglądarce, jak i przeglądarka/cURL może wysłać do serwera informacje o ciasteczkach jakie są ustawione dla danej domeny. Ciasteczka oczywiście możemy preparować sami, a odbywa się to za pomocą stworzenia prostego ciągu z nazwami i wartościami naszych ciasteczek, a nastepnie wysłaniu żądania na serwer. Spójrzmy więc jak to wygląda w praktyce.

Przygotowanie ciasteczek - CURLOPT_COOKIE

W najprostrzej możliwej postaci musimy przygotować ciąg o następującej strukturze:
[code]$cookies = "cookie1=".urlencode("wartość1")."; cookie2=".urlencode("wartość2");  // i tak dalej[/code]
Wszystkie ciastecznka muszą być rozdzielone średnikiem, a ich wartości potraktowane funkcją urlencode().

Nastepnie taki ciąg ustawiamy jako opcję w cURL-u za pomocą parametru CURLOPT_COOKIE:
[code]curl_setopt($ch, CURLOPT_COOKIE, $cookies);[/code]
Całość wysyłamy na serwer.
Nasz kod wyglądać więc będzie tak:
[code]<?php
// do tej tablicy odbierzemy nagłówki
$return_headers = [];
$errors = '';

// funkcja odbierająca nagłówki
function headerLine($curl, $header_line ) {
    $GLOBALS['return_headers'][] = $header_line;
    return strlen($header_line);
}

// url do server.php
$url_to_server = 'http://localhost/server.php';

// inicjujemy sesję połączenia
$ch = curl_init($url_to_server);

// definiujemy cookies
$cookies = "cookie1=".urlencode("this_is_cookie1").";cookie2=".urlencode("this_is_cookie2");

// dodajemy cookies do żądania:
curl_setopt($ch, CURLOPT_COOKIE, $cookies);

// ustawiamy opcje
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // chcemy odebrać dane
curl_setopt($ch, CURLOPT_USERAGENT, 'fake browser'); // ustawiamy user-agenta
curl_setopt($ch, CURLOPT_REFERER, 'http://www.google.com'); // ustawiamy referera
curl_setopt($ch, CURLOPT_HEADERFUNCTION, "headerLine"); // ustawiamy własną funkcję do przetworzenia nagłówka


// wykonujemy połączenie
$response_body = curl_exec($ch);

// pobieramy błąd, jeśli wystąpi
if (curl_errno($ch))  $errors.= '<h2>Error #' . curl_errno($ch) . ': ' . curl_error($ch).'</h2>';

// zamykamy sesję połączenia
curl_close($ch);
?>[/code]

Wysłane ciasteczka pojawią się po stronie serwera w tablicy $_COOKIE:



Ciasteczka wysyłane przez serwer

A jak sprawa wygląda w drugą stronę, gdy to serwer wysyła do nas żądanie ze stworzeniem ciasteczka? Zobaczymy to w nagłówku otrzymanym od serwera:


Jak widać dostaliśmy nagłówek Set-Cookie, który wysyła do nas ciasteczko sesyjne o nazwie PHPSESSID i wartości w tym przypadku 04bc39avas8hvkks9458b8toe7. Analogicznie przesyłane są do nas wszystkie inne ciasteczka, informujące o zalogowaniu i inne, ustawiane w PHP za pomocą funkcji setcookie().

Aby to przeanalizować, dodajmy na początku pliku server.php następujący kod:
[code]<?php
setcookie('cookie_from_server', 'test123');[/code]
i sprawdźmy co się stało w clients.php - jak widać otrzymaliśmy od serwera nagłówek z nowym ciasteczkiem:


Ustawianie flagi HttpOnly

Domyślnie przesyłane przez PHP ciasteczko nie ma ustawionej opcji HttpOnly, a więc może zostać odczytane przez Javascript. Aby wymusić na przeglądarce ustawienie takiej opcji, musimy ustawić cookie poprzez:
[code]<?php
setcookie('cookie_from_server', 'test123', 0, '/', 'localhost', false, true);[/code]
gdzie składnia wygląda następująco:
[code]setcookie(nazwa_cookie, wartość_cookie, czas_ważności, domena, https, httponly)[/code]


Ciasteczko z pliku

Cookies można też zapisać w pliku i wysłać je prosto z pliku.
Służy do tego opcja:
[code]curl_setopt($ch, CURLOPT_COOKIEFILE, '/ścieżka/absolutna/do/pliku');[/code]
Uwaga: ścieżka MUSI być absolutna, nie możemy tutaj podać:
[code]cookies.txt[/code]
Musimy podać, np.:
[code]C:/WWW/test/cookies.txt[/code]
lub wykorzystać:
[code]realpath('cookies.txt')[/code]

Nasz plik cookies.txt może wyglądać następująco:
[code]
localhost   TRUE    /   FALSE   0   cookie_from_file1    cookie_value1
localhost   TRUE    /   FALSE   0   cookie_from_file2    cookie_value3
[/code]

Składnia wygląda następująco:
[code]domena   dostęp_dla_poddomen   ścieżka   czas_wygaśnięcia   nazwa_cookie   wartość_cookie[/code]
Pola oddzielamy tabulatorem, nie spacją, a każde ciasteczko to oddzielna linijka.
Gdy domenę ustawimy z kropką na początku:
[code].localhost[/code]
i podamy TRUE w dostępie do poddomen, to ciastko będzie dostępne również dla subdomen, jak np. test.localhost, www.localhost, test2.localhost itd.

Przykład użycia:
[code]<?php
$return_headers = [];

function headerLine($curl, $header_line ) {
    $GLOBALS['return_headers'][] = $header_line;
    return strlen($header_line);
}
$url_to_server = 'http://localhost/server.php';
$ch = curl_init($url_to_server);
$cookie_file = 'cookies.txt';

curl_setopt($ch, CURLOPT_COOKIEFILE, realpath($cookie_file)); // cookie z pliku
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // chcemy odebrać dane
curl_setopt($ch, CURLOPT_HEADERFUNCTION, "headerLine"); // ustawiamy własną funkcję do przetworzenia nagłówka
$response_body = curl_exec($ch);
curl_close($ch);
?>[/code]

Wynik:


Zapisywanie odebranych ciasteczek

Odebrane od serwera cookies cURL może zapisać do określonego przez nas pliku.
Służy do tego opcja:
[code]curl_setopt($ch, CURLOPT_COOKIEJAR, '/absolutna/ścieżka/do/pliku');[/code]
Dzięki tej opcji wszystkie odebrane od serwera ciasteczka, po wykonaniu funkcji curl_close()  zapisane zostaną do pliku, który podaliśmy jako parametr.
Uwaga: ścieżka ponownie MUSI być absolutna, nie możemy tutaj podać:
[code]returned_cookies.txt[/code]
Musimy podać, np.:
[code]C:/WWW/test/returned_cookies.txt[/code]
lub wykorzystać:
[code]realpath('returned_cookies.txt')[/code]

Przykład użycia:
[code]<?php
$return_headers = [];

function headerLine($curl, $header_line ) {
    $GLOBALS['return_headers'][] = $header_line;
    return strlen($header_line);
}
$url_to_server = 'http://localhost/server.php';
$ch = curl_init($url_to_server);
$cookie_file = 'returned_cookies.txt';

curl_setopt($ch, CURLOPT_COOKIEJAR, realpath($cookie_file)); // cookie do pliku
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // chcemy odebrać dane
curl_setopt($ch, CURLOPT_HEADERFUNCTION, "headerLine"); // ustawiamy własną funkcję do przetworzenia nagłówka
$response_body = curl_exec($ch);
curl_close($ch);
?>[/code]

W naszym przypadku, plik returned_cookies.txt uzyska taką treść:
[code]# Netscape HTTP Cookie File
# http://curl.haxx.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.

#HttpOnly_.localhost TRUE / FALSE 0 cookie_from_server test123
test5.localhost FALSE / FALSE 0 PHPSESSID 04h6239oieslvfhqajtdls7nf0[/code]


Oficjalny, pełny manual biblioteki cURL znajduje się tutaj: http://php.net/manual/en/book.curl.php

Brak komentarzy:

Prześlij komentarz

Masz sugestię? Znalazłeś błąd? Napisz komentarz! :)

webmaester.pl - profesjonalne projektowanie WWW i webaplikacji
webmaester.pl - profesjonalne projektowanie WWW i webaplikacji