Saya baru-baru ini memiliki masalah terkait dan menulis artikel ini tentang itu .
Saya akan menganggap bahwa unduhan diunggah melalui penanganan media WordPress - atau Anda memiliki ID lampiran untuk unduhan.
Garis besar solusi
- Jadikan direktori unggahan 'aman' (Dalam hal ini, saya hanya bermaksud menggunakan
.htaccess
untuk memblokir segala upaya untuk secara langsung mengakses file dalam direktori unggahan (atau sub-direktori daripadanya) - misalnya via mysite.com/wp-content/uploads/conf/2012/09/myconfidentialfile.pdf
)
- Buat tautan unduhan termasuk ID lampiran - ini melewati WordPress untuk memeriksa izin pengguna untuk melihat izin lampiran / menolak akses.
Peringatan
- Ini memanfaatkan
.htaccess
untuk memberikan keamanan . Jika ini tidak tersedia / dihidupkan (server nginx misalnya), maka Anda tidak akan mendapatkan banyak keamanan. Anda dapat mencegah pengguna menelusuri direktori uplods. Tetapi akses langsung akan bekerja.
- Seperti di atas. Ini tidak boleh digunakan dalam distribusi jika Anda memerlukan keamanan mutlak . Tidak masalah jika pengaturan khusus Anda berfungsi - tetapi secara umum, itu tidak dapat dijamin. Artikel tertaut saya sebagian mencoba mengatasi ini.
- Anda akan kehilangan thumbnail . Memblokir akses langsung ke folder atau sub-folder akan berarti thumbnail file dalam folder itu tidak dapat dilihat. Artikel tertaut saya sebagian berusaha untuk mengatasi ini.
Memblokir akses langsung
Untuk melakukan ini di folder unggahan Anda (atau subfolder - semua materi rahasia harus berada, di kedalaman apa pun, di dalam folder ini). Tempatkan .htaccess
file dengan yang berikut ini:
Order Deny,Allow
Deny from all
Berikut ini saya berasumsi bahwa Anda akan melampirkan materi rahasia ke jenis posting 'klien'. Setiap media yang diunggah pada halaman edit klien akan disimpan dalam uploads/conf/
folder
Fungsi untuk mengatur direktori unggahan yang dilindungi
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.
}
Mengunggah materi rahasia
/**
* 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' );
}
}
}
Setelah melakukan itu, konten yang diunggah harus berada di dalam uploads/conf
dan mencoba mengaksesnya langsung menggunakan browser Anda seharusnya tidak berfungsi.
Mengunduh Konten
Ini mudah. Url unduhan dapat berupa sesuatu www.site.com?wpse26342download=5
(di mana 5 adalah ID lampiran dari konten yang diunggah). Kami menggunakan ini untuk mengidentifikasi lampiran, memeriksa izin pengguna saat ini dan memungkinkan mereka untuk mengunduh.
Pertama, atur variabel kueri
/**
* 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;
}}
Sekarang siapkan pendengar untuk (mungkin) memicu unduhan ...
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;
}
Komentar terakhir
Kode di atas mungkin mengandung kesalahan bug / sintaksis dan belum diuji, dan Anda menggunakannya dengan risiko Anda sendiri :).
URL unduhan dapat 'dipoles' menggunakan penulisan ulang. Seperti yang dinyatakan dalam komentar Anda dapat menambahkan kosong index.php
di dalam setiap anak folder yang dilindungi untuk mencegah penjelajahan - tetapi ini harus dicegah dengan .htaccess
aturan.
Metode yang lebih aman adalah menyimpan file publik di luar direktori publik. Atau pada layanan eksternal seperti Amazon S3. Untuk yang terakhir Anda harus membuat url yang valid untuk mengambil file dari Amazon (menggunakan kunci pribadi Anda). Kedua hal ini membutuhkan tingkat kepercayaan tertentu pada Host / layanan pihak ketiga Anda.
Saya akan khawatir menggunakan plug-in yang menyarankan mereka menawarkan 'unduhan yang dilindungi'. Saya belum menemukan yang memberikan keamanan yang cukup baik. Tolong jangan peringatan dari solusi ini juga - dan saya akan menyambut setiap saran atau kritik.