一种解决方案可能是直接限制对服务器上文件的访问,但利用url rewrite
显示内容--仅当id 请求中的匹配项。显然,这并不能回答场景中的所有问题,但它确实提供了将url间接转换为文件的概念证明。
上载文件时,可以在user metadata
无需跟踪内容的自定义文件夹。
这基本上提供了对该文件的访问:
http://example.dev/wp-content/uploads/2015/12/8-1200x675.jpg
如果用户ID 1正在请求访问并已登录
http://example.dev/api/file/1/2015/12/8-1200x675.jpg
<小时>
<?php
if ( ! class_exists( \'FileRequest\' ) ):
class FileRequest {
const ENDPOINT_QUERY_NAME = \'api/file\';
const ENDPOINT_QUERY_PARAM = \'__api_file\';
// WordPress hooks
public function init() {
add_filter( \'query_vars\', array ( $this, \'add_query_vars\' ), 0 );
add_action( \'parse_request\', array ( $this, \'sniff_requests\' ), 0 );
add_action( \'init\', array ( $this, \'add_endpoint\' ), 0 );
}
// Add public query vars
public function add_query_vars( $vars ) {
// add all the things we know we\'ll use
$vars[] = static::ENDPOINT_QUERY_PARAM;
$vars[] = \'file\';
$vars[] = \'user\';
return $vars;
}
// Add API Endpoint
public function add_endpoint() {
add_rewrite_rule( \'^\' . static::ENDPOINT_QUERY_NAME . \'/([^/]*)/(\\S+)/?\', \'index.php?\' . static::ENDPOINT_QUERY_PARAM . \'=1&user=$matches[1]&file=$matches[2]\', \'top\' );
//////////////////////////////////
flush_rewrite_rules( false ); //// <---------- REMOVE THIS WHEN DONE
//////////////////////////////////
}
// Sniff Requests
public function sniff_requests( $wp_query ) {
global $wp;
if ( isset(
$wp->query_vars[ static::ENDPOINT_QUERY_PARAM ],
$wp->query_vars[ \'file\' ],
$wp->query_vars[ \'user\' ] ) ) {
$this->handle_request(); // handle it
}
}
// Handle Requests
protected function handle_request() {
global $wp;
$file = $wp->query_vars[ \'file\' ];
$user = $wp->query_vars[ \'user\' ];
// make sure the request ID is the same as the logged in user
if ( \'\'.get_current_user_id() !== $user ){
wp_send_json_error( array (
\'message\' => \'Unauthorized\',
\'error\' => \'401\',
) );
}
else {
// add the file request to the uploads directory
$upload_dir = wp_upload_dir();
$path = $upload_dir[\'basedir\'].\'/\'.$file;
// make sure url is readable -- if not, stop!
if ( ! is_readable( $path ) ) {
wp_send_json_error( array (
\'message\' => \'Bad Request\',
\'error\' => \'400\',
) );
}
// get files contents
$file_content = file_get_contents( $path );
// get the mime type for headers
$type = get_post_mime_type( $file_content );
// output headers
nocache_headers();
header( "Content-type: $type;" );
header( "Content-Length: " . strlen( $file_content ) );
// output file data
echo $file_content;
}
die();
}
}
$wpFileRequest = new FileRequest();
$wpFileRequest->init();
endif; // FileRequest