У меня недавно была связанная проблема, и я написал эту статью об этом .
Я предполагаю, что загружаемые файлы загружаются с помощью медиа-обработки WordPress, иначе у вас есть идентификатор вложения для загрузки.
План решения
- Сделать каталог дату загрузки «безопасный» (В этом смысле я просто среднее использование ,
.htaccess
чтобы блокировать любые попытки доступа непосредственно файлы в директории загрузок (или подкаталог таковой) - например , через mysite.com/wp-content/uploads/conf/2012/09/myconfidentialfile.pdf
)
- Создайте ссылку для загрузки, включающую в себя идентификатор вложения - это проходит через WordPress, чтобы проверить разрешение пользователя на просмотр вложения, разрешает / запрещает доступ.
Предостережения
- Это использует
.htaccess
для обеспечения безопасности . Если это недоступно / включено (например, на серверах nginx), вы не получите особой безопасности. Вы можете запретить пользователю просматривать каталог uplods. Но прямой доступ будет работать.
- Согласно выше. Это не должно использоваться при распространении, если вам требуется абсолютная безопасность . Хорошо, если ваша конкретная настройка работает, но в целом это не может быть гарантировано. Моя связанная статья частично пытается решить эту проблему.
- Вы потеряете миниатюры . Блокировка прямого доступа к папке или подпапке будет означать, что миниатюры файлов в этой папке не могут быть просмотрены. Моя связанная статья частично пытается решить эту проблему.
Блокировка прямого доступа
Для этого в папке загрузки (или подпапке - весь конфиденциальный материал должен находиться на любой глубине внутри этой папки). Поместите .htaccess
файл со следующим:
Order Deny,Allow
Deny from all
Далее я предполагаю, что вы будете прикреплять конфиденциальный материал к типу записи «клиент». Все медиафайлы, загруженные на страницу редактирования клиента, будут храниться в uploads/conf/
папке.
Функция для настройки защищенного каталога загрузок
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.
}
Загрузка конфиденциального материала
/**
* 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' );
}
}
}
Сделав это, загруженный контент должен быть внутри, uploads/conf
и попытка доступа к нему напрямую через браузер не должна работать.
Загрузка контента
Это легко. URL-адрес загрузки может быть чем-то www.site.com?wpse26342download=5
(где 5 - идентификатор вложения загруженного контента). Мы используем это, чтобы определить вложение, проверить права доступа текущего пользователя и разрешить его загрузку.
Сначала настройте переменную запроса
/**
* 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;
}}
Теперь настройте слушателя, чтобы (возможно) вызвать загрузку ...
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;
}
Заключительные комментарии
Приведенный выше код может содержать ошибки / синтаксические ошибки и не проверен, и вы используете его на свой страх и риск :).
URL-адрес загрузки может быть «предварительно подтвержден» с помощью переписывания. Как указано в комментариях, вы можете добавить пробел index.php
внутри каждого дочернего элемента защищенной папки, чтобы предотвратить просмотр, но в .htaccess
любом случае это должно быть предотвращено правилами.
Более безопасный способ - хранить публичные файлы вне публичного каталога. Или на внешнем сервисе, таком как Amazon S3. Для последнего вам потребуется сгенерировать действительный URL для получения файла из Amazon (используя ваш закрытый ключ). Оба из них требуют определенного уровня доверия к вашему хосту / стороннему сервису.
Я бы с осторожностью использовал любые плагины, которые предлагают «защищенные загрузки». Я не нашел ни одного, обеспечивающего достаточно хорошую безопасность. Пожалуйста, не будьте осторожны с этим решением - и я буду рад любым предложениям или критике.