我最近遇到了一个相关的问题wrote this article about it.
我假设下载是通过WordPress的媒体处理上传的,或者你有下载的附件ID。
解决方案概要使上传目录“安全”(从这个意义上说,我只是想使用.htaccess
阻止直接访问上载目录(或其子目录)中文件的任何尝试-例如,通过mysite.com/wp-content/uploads/conf/2012/09/myconfidentialfile.pdf
)创建包含附件ID的下载链接-通过WordPress检查用户查看附件的权限允许/拒绝访问注意事项This makes use of .htaccess
to provide security. 如果这不可用/未打开(例如,nginx服务器),那么您将不会获得太多安全性。您可以阻止用户浏览uplods目录。但直接访问将起作用如上所述。This should not be used in distribution if you require absolute security. 如果您的特定设置起作用,这是很好的-但一般来说,它不能保证。我的链接文章部分是为了解决这个问题
- You will loose thumbnails. 阻止直接访问文件夹或子文件夹将意味着无法查看该文件夹中文件的缩略图。我的链接文章部分是为了解决这个问题
要在上载文件夹(或子文件夹-所有机密材料必须位于此文件夹的任何深度)中执行此操作,请阻止直接访问。放置a.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是上传内容的附件ID)。我们使用它来识别附件,检查当前用户的权限并允许他们下载。
首先,设置查询变量
/**
* 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获取文件(使用您的私钥)。这两者都需要对主机/第三方服务具有一定程度的信任。
我会小心使用任何建议他们提供“受保护下载”的插件。我还没有找到足够安全的。请不要对这个解决方案提出警告,我欢迎任何建议或批评。