Post Data con le CURL (libcurl)
In questo mini articolo vi spiegherò una delle funzionalità che si possono avere grazie a questa libreria php. Spesso mi capitava di dover avere nelle mie pagine risposte da altri server, come ad esempio autentificazione presso altri sistemi diversi dal mio e poi doverne sfruttare le sessioni per le successive connessioni o dover richiamare miei stessi script, ma vediamo una semplice autentificazione. Prima di tutto è necessario avere tale libreria installata sul proprio webserver apache, nel caso ne foste sprovvisti visionate questo link (Installare le Curl).
Le Curl permettono di collegarsi e comunicare con parecchi tipi di server e con parecchi tipi di protocolli. Libcurl al momento supporta i protocolli http, https, ftp, gopher, telnet, dict, file, e ldap. libcurl supporta anche i certificati HTTPS, HTTP POST, HTTP PUT, l’upload via FTP (questo può essere ottenuto anche con l’estensione ftp di PHP), upload attraverso una form HTTP, proxy, cookie e autenticazione con utente e password. Come sempre un esempio vale più di mille parole, bene l’obbiettivo che ci propone di raggiungere sarà quello inviare da un SERVER A dei dati in $_POST a un SERVER B lavorarli e poi dare risposta. In caso di successo (+OK) faremo una seconda chiamate al SERVER B per vedere stampate le sue sessioni autenticate.
Passi da seguire
- Nel web server creo una cartella denominata SERVER_A
- Nel web server creo una cartella denominata SERVER_B
- SERVER A:Creo il file con il codice CURL (send.php)
- SERVER B:Creo il file con il listen.php che contiene il codice con le risposte ai $_POST data
- SERVER B:creo il file home.php che deve solo stampare le $_SESSION
![]() SCHEMA DI LAVORO |
FILE listen.php (SERVER B)
Questo file si attende 2 variabili in $_POST e sono rispettivamente $_POST["login"] e $_POST["password"], quello che verrà eseguito sarà il semplice controllo che siano corrispondenti alle 2 variabili definite nello stesso file listen.php ($UserName=”pippo” $Password=”pluto“). Il file darà come risposta +OK o +KO in caso di autentificazione non corretta. Se l’autentificazione è corretta saranno impostate le 2 variabili di sessione $_SESSION["UserName"] e $_SESSION["Password"] sul SERVER B.
Bene vediamo il codice del primo file depositato nel SERVER B
#Variabili statiche
$UserName="pippo";
$Password="pluto";
#Un minimo di sicurezza sui dati ricevuti, attendiamoci solo lettere,numeri
if(!empty($_POST["login"]) & !empty($_POST["password"]))
{
#iniziamo a pulire i dati
$_POST["login"]=htmlentities($_POST["login"],ENT_QUOTES,"UTF-8");
$_POST["password"]=htmlentities($_POST["password"],ENT_QUOTES,"UTF-8");
#verifichiamo che ci siano solo i caratteri desiderati
@preg_match("/^[a-zA-Z0-9]*/",$_POST["login"],$OUTLOGIN);
@preg_match("/^[a-zA-Z0-9]*/",$_POST["password"],$OUTPASSWORD);
if($_POST["login"]==$OUTLOGIN[0] & $_POST["password"]==$OUTPASSWORD[0])
{
#Verifichiamo che siano i dati combacianti
if($_POST["login"]==$UserName & $_POST["password"]==$Password)
{
#SUCCESSO!!!
session_start();
$_SESSION["UserName"]=$UserName;
$_SESSION["Password"]=$Password;
echo "+OK";
exit;
}else{echo "+KO";exit;}
}else{echo "+KO";exit;}
}else{echo "+KO";exit;}
Benissimo, ora guardiamo il codice del file send.php presente nel SERVER_A
FILE send.php (SERVER A)
$SERVER_B="http://127.0.0.1/SERVER_B"; #Inizializzo la CURL $UrlInit = curl_init($SERVER_B."/listen.php"); #------------------------- # OPZIONI CURL #------------------------- curl_setopt($UrlInit, CURLOPT_POST, true);#Eseguiamo un POST di dati curl_setopt($UrlInit, CURLOPT_POSTFIELDS, "login=pippo&password=pluto");#$_POST da inviare Variabile=valore curl_setopt($UrlInit, CURLOPT_HEADER, true);# Richiediamo le intestazione Html curl_setopt($UrlInit, CURLOPT_FOLLOWLOCATION, false);#Non seguiamo eventuali redirect curl_setopt($UrlInit, CURLOPT_RETURNTRANSFER, true);#Chiediamo il contenuto della pagina curl_setopt($UrlInit, CURLOPT_TIMEOUT, 30);#Settiamo un timeout di 30 secondi #Eseguiamo la CURL $Curl = curl_exec($UrlInit); #Chiudiamo la connessione curl_close($UrlInit);
Cosa Succede se carichiamo il file send.php? Di seguito potete vedere cosa contiene la variabile $Curl
Date: Tue, 09 Sep 2008 08:33:30 GMT
Server: Apache/2.2.8 (Win32) PHP/5.2.6
X-Powered-By: PHP/5.2.6
Set-Cookie: PHPSESSID=20b13b36622fbb2509a205fc87fbd95b; 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
Content-Length: 3
Content-Type: text/html
+OK
In rosso ho evidenziato le parti che ci interessano maggiormente e che vado a spiegarvi:
HTTP/1.1 200 OK: Ad ogni richiesta la pagina html deve dare un codice di risposta, nel nostro caso è 200 è ci indica che è stata caricata con successo (non vuol dire che l’auteticazione è riuscita, ma solo che la pagina esiste).
PHPSESSID=20b13b36622fbb2509a205fc87fbd95b;: Session id, questo è il valore importante da catturare, perchè nel SERVER_B siamo stati autenticati con una sessione specifica e dovete ricordarvi che ogni chiamata Curl aprirà una sessione nuova (vediamo tra un’istante come sfruttare quella autenticata). Per capire meglio provate a fare “aggiorna” nel browser sulla pagina send.php, noterete che ogni volta tale valore sarà diverso.
+OK: Questo è il corpo della pagina (body). Come protocollo l’HTML dice che prima vengono le intestazioni (headers) e poi il corpo, questi 2 elementi si separano da una linea vuota.
OK,siamo autenticati a questo punto, dobbiamo ora chiamare la pagina home.php del SERVER_B e vedere stampate le sessioni. Per fare questo dobbiamo:
- Verificare che esista il codice HTTP corretto (200)
- Prelevare l’id di sessione di lavoro.
- effettuare una seconda chiamata CURL a home.php
Per fare la prima e seconda operazione usiamo queste 2 funzioni che ho creato per aiutarci nelle operazioni (allegatele nel file send.php in cima alla pagina).
/** Function CURL_ParseHeader()
* Questa funzione ha il compito di analizzare gli headers solitamente prelevati con una curl
* se esiste HTTP/, viene esploso il dato e verificato i codice, se questo è tra quelli passati alla funzione
* allora la risposta è positiva (2XX sono positivi - 3XX sono positivi ma x redirect)
* sono settati x dafault i valori da 200 a 299
*
* @param string $Response headers da analizzare
* @param numeric $StartHeaders risposta headers inizio
* @param numeric $EndHeaders risposta headers fine
* @return bool true in caso successo o false in caso di headers differrente
*/
function CURL_ParseHeader($Response,$StartHeaders=200,$EndHeaders=299)
{
$HttpHeaders = false;
$Response=strip_tags($Response);
$Strip =explode("\n",$Response);
foreach($Strip as $k=>$v)
{
if(preg_match("/^[HTTP\/]/",$v)==true)
{
$ValHttp =explode(" ",$v);
if($ValHttp[1] >= $StartHeaders &amp;amp;amp;amp;amp;amp;amp;amp; $ValHttp[1] <= EndHeaders)
{$HttpHeaders = true;}
}
}
//verifico se è positiva la risposta
if($HttpHeaders == true)
{return true;}else{return false;}
}
/** Preleva il valore del PHPSESSID negli header che gli vengono passati
* Questa funzione ha il compito di ricere un testo e di verificare la linea dove esiste
* la voce <b>Set-Cookie: PHPSESSID=......;</b>. Una volta trovata esegue il parsing e ne
* estrae il valore. Se non è prensente risponde con un false booleano.
* <br>
* <code>
* include("function_curl.php");
* $Curl = curl_exec($UrlInit);
* $PHPID=CURL_GetIDSession($Curl);
* echo $PHPID;
* #STAMPA l'id di sessione di lavoro.
* </code>
*
* @param string $Header risposta di una curl comprensivo dei suoi header
* @return boolean false in caso di errore,risponde con la id di sessione se corretta
*/
function CURL_GetIDSession($Header="")
{
if($Header!="")
{
if(CURL_ParseHeader($Header)==true)
{
$s=explode("\n",$Header);
foreach($s as $key=>$value)
{
if(preg_match("/^Set-Cookie: PHPSESSID=[\w\W\d]+;/",$value,$y))
{
//Se trovo il +OK setto a true la variabile di controllo del flusso
$Exp=explode("=",$y[0]);
$SSID=substr($Exp[1],0,-1);
}
}
if($SSID!="")
{return $SSID;}
else
{return false;}
}else{return false;}
}else{return false;}
}
Ora sfruttando la funzione CURL_GetIDSession($Curl) saremo in grado di catturare l’id di sessione di lavoro del SERVER_B.
Aggiungiamo l’ultimo pezzo di codice al send.php per permetterci di eseguire una seconda CURL verso la pagina home.php
FILE home.php (SERVER B)
session_start(); echo "ID SESSIONE:".session_id()."<br>"; echo "<pre>"; print_r($_SESSION); echo "<pre>";
FILE send.php (SERVER A) Seconda CURL
$PHPSESSID=CURL_GetIDSession($Curl); $UrlInit_2 = curl_init($SERVER_B."/home.php"); curl_setopt($UrlInit_2, CURLOPT_HEADER, false); curl_setopt($UrlInit_2, CURLOPT_FOLLOWLOCATION, false); curl_setopt($UrlInit_2, CURLOPT_RETURNTRANSFER, true); curl_setopt($UrlInit_2, CURLOPT_TIMEOUT, 30); curl_setopt($UrlInit_2, CURLOPT_COOKIE,"PHPSESSID=".$PHPSESSID); $Curl_2 = curl_exec($UrlInit_2); echo $Curl_2;
ed Ecco cosa sarà stampato:
Array
(
[UserName] => pippo
[Password] => pluto
)
Per pulizia mostriamo l’intero codice della pagina send.php
/** Function CURL_ParseHeader()
* Questa funzione ha il compito di analizzare gli headers solitamente prelevati con una curl
* se esiste HTTP/, viene esploso il dato e verificato i codice, se questo è tra quelli passati alla funzione
* allora la risposta è positiva (2XX sono positivi - 3XX sono positivi ma x redirect)
* sono settati x dafault i valori da 200 a 299
*
* @param string $Response headers da analizzare
* @param numeric $StartHeaders risposta headers inizio
* @param numeric $EndHeaders risposta headers fine
* @return bool true in caso successo o false in caso di headers differrente
*/
function CURL_ParseHeader($Response,$StartHeaders=200,$EndHeaders=299)
{
$HttpHeaders = false;
$Response=strip_tags($Response);
$Strip =explode("\n",$Response);
foreach($Strip as $k=>$v)
{
if(preg_match("/^[HTTP\/]/",$v)==true)
{
$ValHttp =explode(" ",$v);
if($ValHttp[1] >= $StartHeaders & $ValHttp[1] <= EndHeaders)
{$HttpHeaders = true;}
}
}
//verifico se è positiva la risposta
if($HttpHeaders == true)
{return true;}else{return false;}
}
/** Preleva il valore del PHPSESSID negli header che gli vengono passati
* Questa funzione ha il compito di ricere un testo e di verificare la linea dove esiste
* la voce <strong>Set-Cookie: PHPSESSID=......;</strong>. Una volta trovata esegue il parsing e ne
* estrae il valore. Se non è prensente risponde con un false booleano.
*
* <code>
* include("function_curl.php");
* $Curl = curl_exec($UrlInit);
* $PHPID=CURL_GetIDSession($Curl);
* echo $PHPID;
* #STAMPA l'id di sessione di lavoro.
* </code>
*
* @param string $Header risposta di una curl comprensivo dei suoi header
* @return boolean false in caso di errore,risponde con la id di sessione se corretta
*/
function CURL_GetIDSession($Header="")
{
if($Header!="")
{
if(CURL_ParseHeader($Header)==true)
{
$s=explode("\n",$Header);
foreach($s as $key=>$value)
{
if(preg_match("/^Set-Cookie: PHPSESSID=[\w\W\d]+;/",$value,$y))
{
//Se trovo il +OK setto a true la variabile di controllo del flusso
$Exp=explode("=",$y[0]);
$SSID=substr($Exp[1],0,-1);
}
}
if($SSID!="")
{return $SSID;}
else
{return false;}
}else{return false;}
}else{return false;}
}
$SERVER_B="http://127.0.0.1/SERVER_B";
#Inizializzo la CURL
$UrlInit = curl_init($SERVER_B."/listen.php");
#-------------------------
# OPZIONI CURL
#-------------------------
curl_setopt($UrlInit, CURLOPT_POST, true);#Eseguiamo un POST di dati
curl_setopt($UrlInit, CURLOPT_POSTFIELDS, "login=pippo&password=pluto");#$_POST da inviare Variabile=valore
curl_setopt($UrlInit, CURLOPT_HEADER, true);# Richiediamo le intestazione Html
curl_setopt($UrlInit, CURLOPT_FOLLOWLOCATION, false);#Non seguiamo eventuali redirect
curl_setopt($UrlInit, CURLOPT_RETURNTRANSFER, true);#Chiediamo il contenuto della pagina
curl_setopt($UrlInit, CURLOPT_TIMEOUT, 30);#Settiamo un timeout di 30 secondi
#Eseguiamo la CURL
$Curl = curl_exec($UrlInit);
#Chiudiamo la connessione
curl_close($UrlInit);
$PHPSESSID=CURL_GetIDSession($Curl);
$UrlInit_2 = curl_init($SERVER_B."/home.php");
curl_setopt($UrlInit_2, CURLOPT_HEADER, false);
curl_setopt($UrlInit_2, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($UrlInit_2, CURLOPT_RETURNTRANSFER, true);
curl_setopt($UrlInit_2, CURLOPT_TIMEOUT, 30);
curl_setopt($UrlInit_2, CURLOPT_COOKIE,"PHPSESSID=".$PHPSESSID);
$Curl_2 = curl_exec($UrlInit_2);
echo $Curl_2;
Questo chiaramente è un semplice esempio di come le CURL possano essere utilizzate, nel mio lavoro ho dovuto spesso eseguire autentificazioni tra diverse piattaforme, come ad esempio dovermi connettere a una casella email in imap e catturare delle mail, oppure connettermi ad altri pannelli senza far inserire password ai cliente, etc..
Trucco
potrebbe capitare di dovere usare le CURL su pagine dello stesso vostro sito, in quel caso la sessione non sarà impostabile in quanto essendo voi in un vostro script lo state occupando in scrittura, per aggirare il problema, prima di settarlo come curl_setopt eseguite un session_write_close();
Potete Scaricare il file rar con le 2 cartelle con relativi file di esempio


(3 votes, average: 6,67 out of 7)