Il web server non ha "memoria" delle comunicazioni HTTP successive, anche se arrivano dallo stesso client. Nelle richieste HTTP ci sono i parametri che contengono le risorse che state cercando, immagini, video, file statici o sempre di più file dinamaci, in PHP. Questo protocollo non ha memoria di comunicazioni successive, e quindi non mantiene lo stato, se ci sono siti con il login bisogna mantenere la memoria.
Per questo motivo, per realizzare applicazioni web complesse, sono stati introdotti altri meccanismi
Cookie, introdotti negli anni 90 da Netscape per gestire il carrello. Access Control, controllo degli accessi implementati sul server Session Control, realizzare sessioni tengono traccia dell'utente durante le sue interazioni COOKIE: DEFINIZIONE
“ ... a cookie is a bit of text, containing some unique information, that web servers send in the HTTP header. The client's browser keeps a list of cookies and web sites. When the user goes back to a web site, the browser will automatically return the cookie, provided it hasn't expired ... ”
Vedi: http://en.wikipedia.org/wiki/HTTP_cookie
I Cookie sono una sequenza di caratteri, che contiene informazioni univoche, vi spedisce in uno dei header HTTP.
Il browser quando riceve questa sequenza lo salva e ne tiene traccia, quando torniamo su questo sito il browser ha già il cookie registrato, sempre che non sia scaduto perchè ha una durata.
COOKIE: FORMATO
Un cookie è una stringa di testo formata da diverse parti (separate da ; ) alcune opzionali:
Name = <VALUE>; <- obbligatorio Expires = <DATE>; possono avere una data, se non si specifica dura finche non si chiude il browser. Path = <PATH>; per quale insieme di pagine è valido il cookie Domain = <DOMAIN_NAME>; nome del sito che rilascia il cookie Secure -> se è sicuro il trasferimento https:// HttpOnly -> non sono leggibili via javascript SameSite -> non può essere inviato ad altri siti COOKIE: RISPOSTA HTTP
Un cookie viene memorizzato nel browser se il server include l'header Set-Cookie: come parte di una risposta HTTP
Un ipotetico cliente associato questa stringa, e con scadenza il 16 dicembre:
Set-Cookie: customer=56FRP13456UYH; domain=.trenitalia.com; expires=Wednesday, 16-Dec-20 ATTENZIONE: non mettere mai dati sensibili nei cookie, perchè si trovano sul client e sono modificabili
Quando un utente torna su un sito che ha già visitato e che gli ha "lasciato" un cookie, il suo browser invia automaticamente il cookie (la coppia name=<VALUE>) come parte della sua richiesta HTTP
Cookie: customer=56FRP13456UYH;
Un browser dovrebbe essere in grado di memorizzare
almeno 300 cookie al massimo 4 KB per cookie un massimo di 20 cookie dallo stesso server (o dominio) Come creare i cookie in PHP?
setcookie (string name, string value, int expire, string path, string domain, bool secure, bool httponly)
Vedi: http://www.w3schools.com/php/php_cookies.asp
http://www.w3schools.com/php/func_http_setcookie.asp
Quando si torna su un sito che ha già lasciato un cookie, il browser invia nell'header della richiesta HTTP il valore del cookie
Sul server questo valore può essere letto in
$_COOKIE $HTTP_COOKIE_VARS Si può portare la data di scadenza del cookie al passato
Si può assegnare al cookie il valore nullo
<?php // if cookie exists if (isset($_COOKIE["mycookie"])) { read the value of the cookie return a personalized welcome back message } else { show registration module } ?>
Creazione di un cookie
<?php ... $cname=”mycookie”; $cvalue = “cookie value here”; $cexpires = mktime(0,0,0,01,01,2021); setcookie($cname,$cvalue,$expires); ?>
Cancellazione del cookie
<?php // set the expiration date to one hour ago setcookie("mycookie", "", time()-3600); ?>
Sono impostati da un sito web diverso da quello che si sta attualmente visitando. Sono usati dagli inserzionisti pubblicitari che li utilizzano per tenere traccia delle visite su tutti i siti sui quali offrono i propri servizi
Secondo quanto previsto dal Regolamento generale sulla protezione dei dati personali (GDPR) dell'UE, ogni sito web deve permettere agli utenti europei dei controllare l'attivazione dei cookie e dei tracker che raccolgono i loro dati personali.
E' possibile disabilitare i cookie (soprattutto di terze parti) ma spesso i siti web che vivono di pubblicità smettono di funzionare
Per esempio si può usare AdBlock
https://it.wikipedia.org/wiki/AdBlock
Per maggior informazioni sui cookie, vi consiglio la pagina Using HTTP cookies.
ESEMPIO PRATICO
Index.php (pagina principale con i Cookie, se si accede direttamente non ha nessun stile CSS e quindi non è formattato; issset() funzione già vista; il nome stile del Cookie; explode() già visto per dividere la stringa; e poi apriamo il tag body e tramite la posizione degli array aggiorniamo i css)
<!DOCTYPE html> <html lang="it"> <head> <title>Homepage</title> <style> <?php if (isset($_COOKIE["stile"])) { $val = $_COOKIE["stile"]; $prop = explode("|", $val); echo "\tbody {\n"; echo "\t\t$prop[0];\n"; echo "\t\t$prop[1];\n"; echo "\t\t$prop[2];\n"; echo "\t}\n"; } ?> </style> </head> <body> <h1>Lorem Ipsum</h1> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus sem tellus, sagittis eu molestie non, venenatis vel lectus. Etiam sapien sem, efficitur ut lacus at, volutpat sodales nibh.</p> <p> Proin dapibus risus congue, cursus libero sit amet, bibendum lectus. Morbi a hendrerit mi. Phasellus feugiat nulla eros, pellentesque congue felis dictum eu. In hac habitasse platea dictumst.</p> <p><a href="personalize.php">Vai alla pagina di personalizzazione</a></p> </body> </html>
Personalize.PHP (Abbiamo il Form per personalizzare il documento sopra con il metodo POST)
<!DOCTYPE html> <html lang="it"> <head> <title>Personalizza le tue pagine con i cookies</title> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> <div id="mydiv"> <form id="myform" action="setcookie.php" method="POST"> Text color: <input type="color" name="color"> Background: <input type="color" name="background-color"> Font: <select name="font-family"> <option value="0">Select font family</option> <option value="Arial">Arial</option> <option value="Arimo">Arimo</option> <option value="Verdana">Verdana</option> <option value="Ubuntu">Ubuntu</option> </select> <br> <input type="submit" value="Submit"> </form> </div> </body> </html>
Setcookie.PHP (Prendiamo i dati dal Form sopra e creiamo il Cookie con nome, durata e la funzione setcookie(); la funzione header() ci reinderizza nella pagina principale index.php)
<?php $value = ""; if (isset($_POST["color"]) & $_POST["color"] != "#000000") $value .= "color: " . $_POST["color"] . "|"; else $value .= "color: black|"; if (isset($_POST["background-color"]) & $_POST["background-color"] != "#000000") $value .= "background-color: " . $_POST["background-color"] . "|"; else $value .= "background-color: white|"; if (isset($_POST["font-family"]) & $_POST["font-family"] != "0") $value .= "font-family: " . $_POST["font-family"] . "|"; else $value .= "font-family: serif|"; $name = "stile"; $expires = mktime(0, 0, 0, 01, 01, 2021); setcookie($name, $value, $expires); header("Location: index.php"); exit; ?>
A cosa servono le Sessioni?
La sessione è importante per tenere traccia di quello che stiamo facendo, a differenza dei Cookie che sono salvate su browser, non bisogna mettere informazioni riservate.
Il controllo di sessione permette di tener traccia dell'utente durante la sua interazione con un sito web. Cosi da non richiedere ogni volta username e password ma vengono memorizzati e finche non scade l'utente può navigare nella sessione.
Per gesitre il controllo di sessione si usa l'array superglobale $_SESSION
Inoltre in PHP si associa ad ogni visitatore un identificatore univoco, chiamato session ID. Viene memorizzato in un Cookie nell header e viene scambiato avanti e indietro per tutta la durata, cosi il web server sa che quell'utente è sempre lui.
Vedi: http://www.w3schools.com/php/php_sessions.asp
SESSIONE COME FARE?
Iniziare una sessione Creare le variabili di sessione Usare le variabili di sessione Distruggere le variabili di sessione e chiudere la sessione
sessione_start();
Verifica se l'utente ha già un identificatore di sessione
Se non lo trova, ne crea uno, altrimenti rende accessibili le variabili di sessione già create in precedenza per quell'utente
Quando si usano le sessioni è obbligatorio iniziare tutti gli script delle pagine riservate con session_start().
$_SESSION["myvar"] = <valore>;
La variabile di sessione viene creata assegnando una chiave all'array superglobale $_SESSION e un valore corrispondente.
La variabile esiste e viene "tracciata" fino a quando non si termina la sessione.
Con isset() si verifica se la variabile di sessione esiste.
if (isset($_SESSION["myvar"])) { ... } else { ... }
Se si, l'utente è autorizzato a proseguire, altrimenti lo si rimanda alla pagina di login.
unset($_SESSION["myvar"]);
La sessione esiste ancora ma la variabile di sessione myvar non è più registrata come variabile di sessione.
session_destroy();
Cancella l'identificatore di sessione.
$_SESSION = array();
Assegnare un array vuoto alla sessione.
<?php session_start(); echo "SID: " . session_id(); ?> ESEMPIO: SID: 0a777aa640f1bad7ac3f788065a99ba6
Nella fase di autenticazione
Si verifica la correttezza dei dati dell'utente Se l'utente è autorizzato, si creano una o più variabili di sessione Si presentano i servizi dell'area riservata
<?php session_start(); /* check user data */ if <login OK> { $_SESSION[“myvar1”] = ...; $_SESSION[“myvar2”] = ...; $_SESSION[“myvar3”] = ...; /* build list of services */ } else { echo “ <h2>You cannot access to these services, check your data</h2>\n ”; } ?>
Durante la navigazione nell'area riservata
Tutti i file che offrono servizi devono controllare le variabili di sessione, non basta il controllo sul primo file!
<?php session_start(); if (!isset($_SESSION[“myvar1”])) { echo “<h2>Access denied</h2>\n”; <present login module>; } else { /* show reserved page */ } ?>
PHP7: HEADER()
Permette di inviare header HTTP al client
Importante: dovrebbe essere invocata prima di restituire al client dati in output, basta anche un solo spazio vuoto (o una riga vuota nel file PHP cui corrisponde il carattere "\n") per causare un errore.
header('Location: URL') // redirect header('Content-type: image/jpg') // MIME type header('Cache-Control: no-cache, must-revalidate') // no cache header('Expires: Mon, 26 Jul 2010 05:00:00 GMT') // date in the past
Nota: bufferizzazione output
PHP invia al client qualunque output non appena disponibile. E'
possibile salvare temporaneamente quello che dovrebbe essere
restituito in output fino a quando non viene detto esplicitamente di spedirlo.
Così facendo, header e dati vengono inviati in modo corretto
anche se alcuni header sono stati creati dopo i primi output HTML
Per abilitare questa funzionalità si può usare la funzione
ob_start() oppure si può attivare la direttiva
output_buffering = 4096 // 4096 sono i byte bufferizzati
Access Control
HTTP è stateless e nasce per lo scambio di risorse. Abbiamo problemi di autorizzazione, e come visto sopra ci viene in aiuto la gestione delle sessioni e ancora prima quella dei Cookie. Nel caso di risorse ad accesso riservato è necessario usare degli accorgimenti
Esistono diverse tecniche, più o meno semplici da implementare, più o meno sicure...
URL nascoste Controllo basato sull'indirizzo IP o sul nome di dominio Controllo basato sull'identità dell'utente
I controlli basati sull'identità dell'utente o sull'indirizzo IP possono essere demandati al server web sfruttando la Basic Authentication di HTTP
Vediamo il caso degli utenti
Quando si cerca di accedere a informazioni protette
- il browser visualizza una finestra di dialogo che richiede le credenziali all'utente
- le credenziali vengono scambiate tra browser e server per tutta la durata dell'interazione
Risposta HTTP di tipo 401:
HTTP/1.1 401 Authorization Required Date: Tue, 04 Mar 2016 17:09:06 GMT Server: Apache/1.3.34 Ben-SSL/1.55 (Debian) PHP/4.4.4-8+etch2 mod_auth_pam/1.1.1 mod_perl/1.29 DAV/1.0.3 WWW-Authenticate: Basic realm="Restricted Area for My Server." Transfer-Encoding: chunked Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <HTML><HEAD><TITLE>401 Authorization Required</TITLE></HEAD> <BODY> <H1>Authorization Required</H1>This server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required.<P></BODY></HTML>
Si può creare un file di testo .htaccess nella directory che si vuole proteggere e specificare delle direttive
Vedi: http://httpd.apache.org/docs/current/howto/auth.html
AuthType Basic AuthName “Restricted Area for My Server” AuthUserFile /absolutepath/nomefilepwd Require valid-user * invece di scrivere valid-user, si possono elencare gli utenti che possono accedere, oppure un gruppo di utenti
Le credenziali degli utenti possono essere salvate in un file di testo, specificando la direttiva
AuthBasicProvider file
Con il file di testo ci sono problemi di efficienza (il file viene letto per ogni accesso alle risorse nell'area protetta) e si possono anche usare formati di storage come dbm e dbd, o LDAP
AuthBasicProvider dbm
AuthBasicProvider ldap
Il file delle password si crea con il comando htpasswd (-c si deve usare solo la prima volta che si crea il file delle password)
htpasswd –c nomefilepwd nomeuser New password: ********* Re-type new password: ********* Nota: Il file .htaccess e quello delle password devono essere leggibili dal web server (chmod 644)
Per ogni accesso ad una pagina protetta, il server deve leggere dalla richiesta HTTP le credenziali e poi accedere a
- file .htaccess
- file/database/LDAP per la password
Se il numero degli utenti cresce, questo meccanismo di autenticazione diventa inefficiente
- Read more...
- 0 comments
- 701 views