私は、弁護士のために作られたサイトと彼のクライアントのそれぞれが、wp-adminなどにアクセスすることなく彼ら自身の '特定のページ/ポータル'(カスタム投稿タイプ)にログインできるという非常に特殊なユースケースを持っています。フロントエンドのログイン/登録/プロフィール編集ページ)このページ/ポータルでは、弁護士はメッセージとクライアントがダウンロードするファイルを残します。プライバシー/セキュリティ/機密資料などの問題.
私は解決策のアイデア/概念を探しています、私の最初の考えは、添付ファイルID、ユーザーID、ページ/ポータルID、およびnonceを送信するダウンロードリンクへのダウンロードを指すことです。 。
どう思いますか?私は正しい方向に進んでいるのか、それともこのアプローチに欠陥があるのか?
ありがとうございます。
何が起こる必要があるのはあなたがWordPressを通してあなたが望むファイルタイプのために代理ダウンロード要求をする必要があるということです。 「.doc」ファイルへのアクセスを制限するとしましょう。
function add_get_file_query_var( $vars ) {
$vars[] = 'get_file';
return $vars;
}
add_filter( 'query_vars', 'add_get_file_query_var' );
これにより、制限したいファイルへのリクエストをキャプチャし、上記のカスタムクエリ変数を使用してそれらをWordPressに送り返します。 RewriteCond
行の前に次の規則を挿入します。
RewriteRule ^wp-content/uploads/(.*\.docx)$ /index.php?get_file=$1
function intercept_file_request( $wp ) {
if( !isset( $wp->query_vars['get_file'] ) )
return;
global $wpdb, $current_user;
// Find attachment entry for this file in the database:
$query = $wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE guid='%s'", $_SERVER['REQUEST_URI'] );
$attachment_id = $wpdb->get_var( $query );
// No attachment found. 404 error.
if( !$attachment_id ) {
$wp->query_vars['error'] = '404';
return;
}
// Get post from database
$file_post = get_post( $attachment_id );
$file_path = get_attached_file( $attachment_id );
if( !$file_post || !$file_path || !file_exists( $file_path ) ) {
$wp->query_vars['error'] = '404';
return;
}
// Logic for validating current user's access to this file...
// Option A: check for user capability
if( !current_user_can( 'required_capability' ) ) {
$wp->query_vars['error'] = '404';
return;
}
// Option B: check against current user
if( $current_user->user_login == "authorized_user" ) {
$wp->query_vars['error'] = '404';
return;
}
// Everything checks out, user can see this file. Simulate headers and go:
header( 'Content-Type: ' . $file_post->post_mime_type );
header( 'Content-Dispositon: attachment; filename="'. basename( $file_path ) .'"' );
header( 'Content-Length: ' . filesize( $file_path ) );
echo file_get_contents( $file_path );
die(0);
}
add_action( 'wp', 'intercept_file_request' );
_ nb _ この解決法はシングルサイトインストールに有効です のみ !これはWordPress MUがwp-includes/ms-files.php
を通して既にアップロードされたファイルリクエストをサブサイトに転送しているためです。 WordPress MUにも解決策がありますが、もう少し複雑です。
私は最近、関連する問題に遭遇しました それについてこの記事を書きました 。
ダウンロードは、WordPressのメディア処理を介してアップロードされることを前提としています。そうでない場合は、ダウンロード用の添付ファイルIDを持っています。
.htaccess
を使用して、アップロードディレクトリ(またはサブディレクトリ)のファイルへの直接アクセスをブロックすることを意味するその)-例:mysite.com/wp-content/uploads/conf/2012/09/myconfidentialfile.pdf
).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はアップロードされたコンテンツの添付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からファイルを取得する必要があります(秘密キーを使用)。これらは両方とも、ホスト/サードパーティサービスで一定レベルの信頼を必要とします。
私は、それらが「保護されたダウンロード」を提供することを示唆するプラグインの使用について警戒するでしょう。十分なセキュリティを提供するものを見つけていません。この解決策の警告もしないでください-提案や批判を歓迎します。
おそらく、あなたはこのトリックを知っているかもしれません。このコードは現在ログインしているユーザーのユーザー名をチェックし、それが一致すればそのファイルへのダウンロードリンクを表示し、そうでなければ何も表示しません。
これがコードです:
<?php
global $current_user;
get_currentuserinfo();
if ( 'username' == $current_user->user_login ) {
echo 'Download Link';
} else {
// nothing
}
?>
ただし、ファイルはサーバーに保存されているため、リンクを持つ人は誰でもそのファイルをダウンロードできますので、これは適切な方法ではありません。
私は、ファイルの暗号化が上記の答えのようになる方法だと思います。 Wordpress.orgにはダウンロードを保護するためのプラグインがあります。 http://wordpress.org/extend/plugins/download-protect/ amazonサービスまたはGoogleドライブを使用することもできます。ドロップボックスなどの保護されたダウンロードを提供するサービスもたくさんあります。
私はこの情報は機密であると思います。そのため、ユーザーがダウンロードを明示的に許可していない限り、Web上の誰にも完全にアクセスできないファイルへのリンクを隠します。ファイル。
Amazon S3 に安全にファイルを保存してから、正しいセキュリティチェックが満たされている(つまり、ユーザーがログインしている)場合は、 事前署名済み (期限付き)URLをファイルに提供します。サイトであり、彼らが彼らであると言っている人です)。
AWS SDK という非常に優れたものがあり、これを実行するのは非常に簡単です。
調査する必要があるのは、WPアップロードインターフェイスを介してアップロードされたファイルをS3に送信する方法です。代わりに独自の uploader を作成します。
他の選択肢は、 WP e-commerce のコードを調べてもよいでしょう。彼らはソフトウェアファイル(例えば、MP3)の安全なダウンロードを提供する。購入時にユーザーごとに生成される暗号化キーでファイルがハッシュに変換されると思います。これがどのように機能するかを理解するにはある程度の解読が必要ですが、このプロセスはこのプラグインに固有のものではないので、他の例が利用可能になります(どこかで)。