WordPress のメディアファイルは静的ファイルなので、WordPress のログイン・非ログインにより表示・非表示を制御するということができません。
ただ会員制サイトとかだと、ログインしてない時に直接アクセスさせたくないとかって要望もあるので、対応できるようにしてみました。
まず、WordPress がインストールされてるディレクトリに以下のファイルを作成します。
uploads-files.php
<?php
require __DIR__.'/wp-load.php';
if ( is_user_logged_in() ) {
$file = realpath( ABSPATH . sanitize_text_field($_GET['file']) );
// アップロードディレクトリ以下のファイルのみを対象にする
$upload_dir = wp_get_upload_dir();
if ( $file && strpos( $file, $upload_dir['basedir'] ) == 0 ) {
$mime_type = mime_content_type( $file );
// アップロードが許可されている mime type のファイルのみを対象にする
$allowed_mime_types = get_allowed_mime_types();
if ( in_array( $mime_type, $allowed_mime_types, true ) ) {
if ( $mime_type === 'image/svg' ) {
$mime_type = 'image/svg+xml';
}
header( 'Expires: 0' );
header( 'Cache-Control: must-revalidate' );
header( 'Pragma: public' );
header( 'Content-Length: ' . filesize( $file ) );
header( 'Content-Type: ' . $mime_type );
header( 'X-Content-Type-Options: nosniff' );
while ( ob_get_level() ) { ob_end_clean(); }
readfile( $file );
exit;
} else {
wp_die(
'403 Forbidden',
get_bloginfo('name').' - Forbidden',
['response' => 403]
);
}
} else {
wp_die(
'404 Not Found',
get_bloginfo('name').' - Not Found',
['response' => 404]
);
}
} else {
wp_die(
'401 Unauthorized',
get_bloginfo('name').' - Unauthorized',
['response' => 401]
);
}
そんで、Nginx の設定ファイルに以下の rewrite ルールを追加。
合わせて /uploads-files.php
に対して直接アクセスされないように internal に設定しておきましょうかね。
nginx.conf
rewrite ^(/wp-content/uploads/.*)$ /uploads-files.php?file=$1 last;
location = /uploads-files.php {
internal;
expires off;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
}
これで /wp-content/uploads/
以下へのリクエストがくると /uploads-files.php
で処理されるようになります。
/uploads-files.php
の中で WordPress にログインしているか( is_user_logged_in()
)をチェックしているので安心ですね。