Può capitare, nel nostro sito, di avere una cartella dove sono contenuti file mp3 o documenti che dovrebbero essere accessibili da una ristretta cerchia di persone. Potete naturalmente nascondere il link che punta a quel file, in modo che solo gli utenti dotati di password possano vederlo e raggiungerlo; ma una volta scoperto il nome e il percorso del file, chiunque potrebbe raggiungerlo scrivendo semplicemente la path nella barra degli indirizzi del browser.
Lo script che vi vado a presentare elimina questo problema alla fonte.
Riassumendo: a priori impediremo a chiunque l’accesso alla cartella (che non sarà accessibile scrivendo il suo percorso sul browser). Tramite uno script in php, faremo in modo che solo gli utenti dotati di password possano accedervi.
Usare l’htaccess per negare l’accesso a una cartella
Iniziamo con il proteggere la cartella.
Quello che dovete fare è creare un file txt e inserirvi all’interno queste direttive:
1 2 3 4 5 |
<Files ~ ".pdf"> Order allow,deny Deny from all Satisfy All </Files> |
Rinominate poi il file come .htaccess
(senza estensioni né altro). Si tratta di un file particolare che il server si premurerà di leggere e di interpretare. Questo file deve essere posto all’interno della cartella da proteggere.
Vediamolo un attimo nel dettaglio. Le direttive qui sopra sono rivolte ai soli file con estensione pdf. Nel caso abbiate immagini dovrà essere sostituito, per esempio, con jpg. Per estendere la funzionalità a qualsiasi file presente nella cartella, dobbiamo cambiare la prima riga in questo modo:
1 |
<Files ~ ".+">
|
La direttiva deny from all
impedisce a chiunque di accedere ai file della cartella con l’estensione scelta.
Permettere l’accesso alla cartella soltanto a chi è provvisto di password
Adesso creiamo un file accesso.php
, anch’esso all’interno della cartella da proteggere, e riempiamolo con queste righe:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
if(isset($_SESSION['password'])){ $nome_file="prova.pdf"; $dimensione_file="249kb"; $percorso_assoluto=""; header("Content-Type: application; name=".$nome_file); header("Content-Transfer-Encoding: binary"); header("Content-Length: ".$dimensione_file); header("Content-Disposition: inline; filename=".$nome_file); header("Expires: 0"); header("Cache-Control: no-cache, must-revalidate"); header("Cache-Control: private"); header("Pragma: public"); readfile($percorso_assoluto.$nome_file); } |
Il file accesso.php
permette di oltrepassare la protezione dell’htaccess che abbiamo creato in precedenza.
Proteggerlo da accessi esterni è molto semplice: basta inserire una condizione che controlli il possesso o meno dei requisiti. Se l’utente che accede a questo file si è loggato (e quindi la variabile $_SESSION["password"]
è definita), potrà avviare lo script e scaricare il file prova.pdf
.
Chiaramente il nome del file può essere reso dinamico. Ci basta, per esempio, far passare il suo nome come variabile $_GET.
Un’annotazione: l’header riguardante la dimensione dei file (Content-Lenght
) non è obbligatorio, serve solo per maggiore sicurezza e potete quindi ometterlo con le dovute modifiche.
Mi interessa molto il tuo post per il seguente motivo:
A scuola stiamo lavorando sulla dematerializzazione dei documenti, fruibili esclusivamente online, e tra questi abbiamo pensato di far scaricare le pagelle da area riservata in modo che ogni genitore possa scaricare esclusivamente quella del proprio figlio con una personale password. Ho provato il tuo script ma ho problemi nel richiamarlo tramite form di accesso. In pratica, come faccio ad entrare in access.php?
Tieni conto che sono un insegnante di matematica e non un informatico anche se me la cavo abbastanza bene.
Resto in attesa di un tuo riscontro.
Buona serata.
Demetrio
Ciao Demetrio,
ti faccio prima di tutto i miei complimenti per l’iniziativa: rendere i documenti digitali significa risparmiare tempo e denaro alla scuola (senza contare le minori trafile burocratiche).
Venendo alla tua domanda, non ho capito bene se hai delle conoscenze di base del php, perché in questo caso ti servono per forza.
Ti rispondo presupponendo che tu abbia un’infarinatura generale (in caso contrario dovresti appoggiarti a qualcuno di un po’ esperto nel settore).
L’idea è semplice: il genitore fa il login nel sito, inserendo la sua password e nome utente. A questo punto ti basta immagazzinare la password nella variabile di sessione. Poi ti basta un semplice link che mandi il genitore al file access.php.
Qua dovrai occuparti tu di controllare che la password sia giusta e quale file il genitore deve scaricare (per esempio controllando nel database, se i riferimenti alle pagelle sono salvati lì, oppure facendolo passare mano come get).
Ciao, grazie x la guida, ma noto che una cosa non va, lo script funziona finche si richiamano direttamente le pagine (tramite url), ma il mio problema e che il blocco tramite url gia lo eseguo su detrminati controlli, mentre devo disattivare la possibilita di eseguire il fileread() su di esso, poiche mi printa il codice sorgente e come puoi immaginare non posso permettermi di far leggere le mie classi….. grazie in anticipo
Ciao Saymon,
se stai usando la funzione php di lettura, ti basta semplicemente impedire a readfile() di “puntare” a quel file. Lo script è tuo immagino, per cui dovresti inserire un if che controlli il nome del file passato a readfile().
Gentilissimo Manuel, stavo provando a creare una simulazione di funzionamento in qui sotto descritta, ma mi dice sempre che non ho permessi per entrare.
1) sul server ho una cartella chiamata “privata” e dentro ho 2 sottocartelle “articoli” e grafici”. articoli contiene i file pdf da proteggere.
2) creato il file .htaccess e messo dentro “privata”
3) ho creato un file chiamato “creasessione.php” per simulare l’avvenuto login e l’ho messo nella cartella superiore a privata, ovvero “trading” e il codice è:
<?php
$pass = "sanz";
session_start();
$_SESSION['password'] = $pass;
echo 'Sessione partita per '. $pass;
echo '’;
echo $_SESSION[‘password’]; //istruzione solo per controllare che la sessione fosse veramente creata 🙂
?>
4) ho messo dentro accesso.php il seguente codice:
5) poi da barra indirizzo browser su altra pagina vado a mettere: http://www.miosito.it/trading/privata/articoli/azioni1.pdf
e mi dice che non ho i permessi.
dove sbaglio? nel percorso assoluto? o devo far puntare da “creasessione.php” direttamente ad accesso.php con un header?
manca forse un controllo su accesso.php ?
grazie mille per la tua disponibilità
Ciao Antonio,
è un po’ complicato capire dove sta l’errore senza avere sottomano tutti i file. Fai questi controlli:
– verifica di essere effettivamente logato (cioè che esista $_SESSION[‘password’])
– verifica che dentro la direttiva readfile() ci sia il percorso corretto
Per fare questi test elimina temporaneamente l’htaccess e stampa a video i valori.