Di recente ho avuto un problema correlato e ho scritto questo articolo a riguardo .
Presumo che i download vengano caricati tramite la gestione dei file multimediali di WordPress o altrimenti si dispone di un ID allegato per il download.
Schema di soluzione
- Rendi la directory dei caricamenti "sicura" (In questo senso intendo solo usare
.htaccess
per bloccare qualsiasi tentativo di accedere direttamente ai file nella directory dei caricamenti (o in una sua sottodirectory) - ad es. Via mysite.com/wp-content/uploads/conf/2012/09/myconfidentialfile.pdf
)
- Crea un collegamento per il download che includa l'ID allegato: questo passa attraverso WordPress per verificare l'autorizzazione dell'utente a visualizzare l'allegato consente / nega l'accesso.
Avvertenze
- Questo utilizza
.htaccess
per fornire sicurezza . Se questo non è disponibile / attivato (ad esempio server nginx), non otterrai molta sicurezza. È possibile impedire all'utente la navigazione nella directory degli uplods. Ma l'accesso diretto funzionerà.
- Come sopra. Questo non dovrebbe essere usato nella distribuzione se si necessita di sicurezza assoluta . Va bene se la tua configurazione specifica funziona, ma in generale non può essere garantita. Il mio articolo collegato sta in parte cercando di risolvere questo problema.
- Perderai le anteprime . Il blocco dell'accesso diretto a una cartella o sottocartella comporterà l'impossibilità di visualizzare le anteprime dei file in quella cartella. Il mio articolo collegato sta in parte tentando di risolvere questo problema.
Blocco dell'accesso diretto
Per fare ciò nella cartella dei caricamenti (o in una sottocartella, tutto il materiale riservato deve risiedere, a qualsiasi profondità, all'interno di questa cartella). Inserire un .htaccess
file con il seguente:
Order Deny,Allow
Deny from all
Di seguito suppongo che allegherai materiale riservato per inserire il tipo "client". Qualsiasi supporto caricato sulla pagina di modifica del client verrà archiviato nella uploads/conf/
cartella
La funzione per impostare la directory di upload protetta
function wpse26342_setup_uploads_dir(){
$wp_upload_dir = wp_upload_dir();
$protected_folder = trailingslashit($wp_upload_dir['basedir']) . 'conf';
// Do not allow direct access to files in protected folder
// Add rules to /uploads/conf/.htacess
$rules = "Order Deny,Allow\n";
$rules .= "Deny from all";
if( ! @file_get_contents( trailingslashit($protected_folder).'.htaccess' ) ) {
//Protected directory doesn't exist - create it.
wp_mkdir_p( $protected_folder);
}
@file_put_contents( trailingslashit($protected_folder).'.htaccess', $rules );
//Optional add blank index.php file to each sub-folder of protected folder.
}
Caricamento materiale riservato
/**
* Checks if content is being uploaded on the client edit-page
* Calls a function to ensure the protected file has the .htaccess rules
* Filters the upload destination to the protected file
*/
add_action('admin_init', 'wpse26342_maybe_change_uploads_dir', 999);
function wpse26342_maybe_change_uploads_dir() {
global $pagenow;
if ( ! empty( $_POST['post_id'] ) && ( 'async-upload.php' == $pagenow || 'media-upload.php' == $pagenow ) ) {
if ( 'client' == get_post_type( $_REQUEST['post_id'] ) ) {
//Uploading content on the edit-client page
//Make sure uploads directory is protected
wpse26342_setup_uploads_dir();
//Change the destination of the uploaded file to protected directory.
add_filter( 'upload_dir', 'wpse26342_set_uploads_dir' );
}
}
}
Fatto ciò, il contenuto caricato dovrebbe trovarsi all'interno uploads/conf
e tentare di accedervi direttamente utilizzando il browser non dovrebbe funzionare.
Download di contenuti
Questo è facile. L'URL di download può essere qualcosa www.site.com?wpse26342download=5
(dove 5 è l'ID allegato del contenuto caricato). Usiamo questo per identificare l'allegato, controllare le autorizzazioni dell'utente corrente e consentire loro di scaricare.
Innanzitutto, imposta la variabile di query
/**
* Adds wpse26342download to the public query variables
* This is used for the public download url
*/
add_action('query_vars','wpse26342_add_download_qv');
function wpse26342_add_download_qv( $qv ){
$qv[] = 'wpse26342download';
return $qv;
}}
Ora imposta un ascoltatore per (forse) attivare il download ...
add_action('request','wpse26342_trigger_download');
function wpse26342_trigger_download( $query_vars ){
//Only continue if the query variable set and user is logged in...
if( !empty($query_vars['wpse26342download']) && is_user_logged_in() ){
//Get attachment download path
$attachment = (int) $query_vars['wpse26342download'];
$file = get_attached_file($attachment);
if( !$file )
return;
//Check if user has permission to download. If not abort.
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit();
}
return $query_vars;
}
Commenti finali
Il codice sopra può contenere bug / errori di sintassi ed è non testato e lo si utilizza a proprio rischio :).
L'URL di download può essere "preimpostato" utilizzando riscritture. Come indicato nei commenti, è possibile aggiungere uno spazio vuoto index.php
all'interno di ogni figlio della cartella protetta per impedire la navigazione, ma ciò dovrebbe essere comunque impedito dalle .htaccess
regole.
Un metodo più sicuro sarebbe quello di archiviare i file pubblici al di fuori di una directory pubblica. O su un servizio esterno come Amazon S3. Per quest'ultimo dovrai generare un URL valido per recuperare il file da Amazon (usando la tua chiave privata). Entrambi richiedono un certo livello di fiducia nel servizio Host / di terze parti.
Sarei diffidente sull'uso di eventuali plug-in che suggeriscono che offrono "download protetti". Non ne ho trovato nessuno che fornisca una sicurezza sufficiente. Per favore, non le avvertenze di questa soluzione - e sarei lieto di ricevere suggerimenti o critiche.