sieci komputerowe, cisco, webmastering, php, css, xhtml, javascript, google, linux, windows server

Połączenia SSL w PHP (klient HTTPS)

Kategorie: PHP | 15 października 2007 13:55 | Odsłon: 4669 | Komentarzy: 7 | Permalink

Ostatnio stanąłem przed problemem utworzenia klienckiego połączenia SSL z poziomu skryptu PHP w celu pobrania pliku przez protokół HTTP. Sprawa okazała się prostsza niż myślałem. Tutaj zamieszczam gotową receptę.

Wymagania

Żeby całość zaczęła chodzić, musimy mieć PHP skompilowane z obsługą OpenSSL. To, czy mamy wkompilowany OpenSSL możemy sprawdzić w wyniku, jaki zwraca funkcja phpinfo(), lub po prostu - wyjdzie w praniu, podczas pisania skryptu.

Założenia ogólne

Cała procedura sprowadza się do utworzenia odpowiedniego nagłówka protokołu HTTP, otwarcia połączenia SSL, wysłania tego nagłówka przez otwarte połączenie oraz odebrania odpowiedzi.

Żeby ułatwić i uczynić skrypt bardziej przejrzystym, przyjmijmy kilka zmiennych:

$host="luktom.net"; $file="/testowy.php"; $get="zmienna1=wartosc1&zmienna2=wartosc2"; $post="zmienna1=wartosc1&zmienna2=wartosc2";

W zmiennych $get i $post zapisujemy zapytania do serwera, które chcemy wysłać daną metodą.

Tworzenie nagłówka

Zasadniczo nie ma znaczenia, czy chcemy wykonać zapytanie GET czy POST. Procedura jest taka sama. W przypadku metody GET nagłówek będzie wyglądał tak:

$request="GET {$file}?{$get} HTTP/1.0\r\n" . "Host: $host\r\n\r\n"

Natomiast dla POST, następująco:

$request="POST {$file}?{$get} HTTP/1.0\r\n" . "Host: $host\r\n" . "Content-Type: application/x-www-form-urlencoded\r\n" . "Content-Length: ".strlen($post)."\r\n\r\n" . "$post\r\n"

Obsługa połączenia SSL

Otwarcie połączenia sprowadza się do pozyskania odpowiedniego deskryptora z funkcji fsockopen:

$fp=fsockopen("ssl://$host", 443, $errno, $errstr, 1);

Dla sprawdzenia, czy połączenie zostało pomyślnie nawiązane sprawdzamy deskryptor:

if(!$fp) { die($errstr); }

Następnie przystępujemy do wysłania zapytania i odczytania odpowiedzi oraz ostatecznie zamykamy połączenie:

fwrite($fp, $request); while(!feof($fp)) { $response.=fgets($fp, 128); } fclose($fp);

Odpowiedź zawiera w sobie nagłówki oraz właściwą treść strony. Rozdzielmy je:

$pos=strpos($response,"\r\n\r\n") $body=substr($response,$pos+4); $headers=substr($response,$pos);

Ostatecznie w zmiennej $body zapisaną mamy treść strony, natomiast w $headers - nagłówki zwrócone od serwera.

Uwagi końcowe

Przedstawiona metoda sprawdza się nie tylko w przypadku protokołu HTTP - równie dobrze możemy np. nawiązać szyfrowane połączenie z serwerem Jabbera lub serwerem pocztowym, jak też każdym innym - wystarczy jedynie poznać ich protokoły oraz odpowiednio dostosować skrypt.

Wpisy o podobnej tematyce

mateusz a

15 października 2007 23:06
Jeśli chodzi o GET przez HTTPS, to sprawa jest jeszcze prostsza:

$f = fopen( "https://login.jogger.pl/login/", "r" );

Pozdrawiam

luktom

17 października 2007 13:50
No faktycznie - w sumie nie opisałem tego sposobu chyba głównie dlatego, że w moim przypadku, dla którego rozgryzałem te połączenia po SSL, bawiłem się też w manipulację nagłówkami HTTP.

wielokropek

17 października 2007 20:04
Nigdy nie próbowałem, ale myślałem, że się da przez za pomocą curl.

ktl

23 października 2007 13:16
W jaki sposób można pobrać dane z serwera wymagającego uwierzytelnienia? Czy login i hasło można wysłać w nagłówku?
Pozdrawiam

luktom

27 października 2007 17:07
To zależy od sposobu uwierzytelniania. W większości przypadków, gdzie realizowane jest to poprzez formularz logowania, wystarczy wysłać odpowiednie pola i wartości, które odczytujemy z kodu formularza (czyli dopisujemy stosowne pary zmienna=wartość do $get lub $post, w zależności od metody przesyłu danych formularza).

GiM

3 listopada 2007 01:03
a co się stanie jak certyfikat wygaśnięty, albo jeszcze lepiej zły?

btw: chyba przez to że jogger we własnej domenie, to nie widzem 'śledź wątek'

zenon bąbalina

5 grudnia 2007 18:35
dzięki za info o połączeniu ssl przez fsockopen. Dużo czasu straciłem na rozgryzanie dlaczego serwer nie chce mi zwracać zawartości tylko się zawiesza - brakowało ssl:// w wywołaniu fsockopen :(

Dodaj komentarz

Token

Statystyka
Ładowanie...