Как защитить файл на поддомене основного сайта от скачивания без авторизации в WordPress - PullRequest
0 голосов
/ 28 августа 2018

Например, мой основной домен www.example.com, который является веб-сайтом для обмена файлами, где мы храним файлы в поддомене, например server1.example.com и server2.example.com, чтобы поделиться с посетителями. Мой вопрос заключается в том, как защитить файл в субдомене (субдомен может указывать на другой сервер или хост) напрямую из загрузки без аутентификации в wordpress / mainsite.

Мой текущий код кредита идет в http://wordpress.stackexchange.com/a/37743/12438

.htaccess файл

RewriteCond %{REQUEST_FILENAME} -s
RewriteRule ^wp-content/uploads/(.*)$ dl-file.php?file=$1 [QSA,L]

ТАК весь мой код .htaccess выглядит как

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]

# BEGIN THIS DL-FILE.PHP ADDITION
RewriteCond %{REQUEST_URI} ^.*wp-content/uploads/.*
RewriteRule ^wp-content/uploads/(.*)$ dl-file.php?file=$1 [QSA,L]
# END THIS DL-FILE.PHP ADDITION

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

Options -Indexes

но он может защитить только файл внутри wp-content/uploads/* вот dl-file.php

<?php
ob_start();
require_once('wp-load.php');
require_once ABSPATH . WPINC . '/formatting.php';
require_once ABSPATH . WPINC . '/capabilities.php';
require_once ABSPATH . WPINC . '/user.php';
require_once ABSPATH . WPINC . '/meta.php';
require_once ABSPATH . WPINC . '/post.php';
require_once ABSPATH . WPINC . '/pluggable.php';
wp_cookie_constants();
$discard = ob_get_clean();

is_user_logged_in() ||  auth_redirect();


list($basedir) = array_values(array_intersect_key(wp_upload_dir(), array('basedir' => 1)))+array(NULL);

$file = rtrim($basedir, '/') . '/' . (isset($_GET['file']) ? $_GET['file'] : '');
$file = realpath($file);

if ($file === FALSE || !$basedir || !is_file($file)) {
    status_header(404);
    die('404 &#8212; File not found.');
}

if (strpos($file, $basedir) !== 0) {
    status_header(403);
    die('403 &#8212; Access denied.');
}


$mime = wp_check_filetype($file);
if( false === $mime[ 'type' ] && function_exists( 'mime_content_type' ) )
    $mime[ 'type' ] = mime_content_type( $file );
if( $mime[ 'type' ] )
    $mimetype = $mime[ 'type' ];
else
    $mimetype = 'image/' . substr( $file, strrpos( $file, '.' ) + 1 );
header( 'Content-Type: ' . $mimetype ); // always send this
if ( false === strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS' ) )
    header( 'Content-Length: ' . filesize( $file ) );
$last_modified = gmdate( 'D, d M Y H:i:s', filemtime( $file ) );
$etag = '"' . md5( $last_modified ) . '"';
header( "Last-Modified: $last_modified GMT" );
header( 'ETag: ' . $etag );
header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + 100000000 ) . ' GMT' );
// Support for Conditional GET
$client_etag = isset( $_SERVER['HTTP_IF_NONE_MATCH'] ) ? stripslashes( $_SERVER['HTTP_IF_NONE_MATCH'] ) : false;
if( ! isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) )
    $_SERVER['HTTP_IF_MODIFIED_SINCE'] = false;
$client_last_modified = trim( $_SERVER['HTTP_IF_MODIFIED_SINCE'] );
// If string is empty, return 0. If not, attempt to parse into a timestamp
$client_modified_timestamp = $client_last_modified ? strtotime( $client_last_modified ) : 0;
// Make a timestamp for our most recent modification...
$modified_timestamp = strtotime($last_modified);
if ( ( $client_last_modified && $client_etag )
    ? ( ( $client_modified_timestamp >= $modified_timestamp) && ( $client_etag == $etag ) )
    : ( ( $client_modified_timestamp >= $modified_timestamp) || ( $client_etag == $etag ) )
    ) {
    status_header( 304 );
    exit;
}
// If we made it this far, just serve the file
readfile( $file );

Ответы [ 2 ]

0 голосов
/ 31 августа 2018

Шаг 1:

Добавьте следующее в '.htaccess' всех поддоменов .

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s

RewriteCond %{QUERY_STRING} !key=(FgTyUeL)
RewriteRule ^(.*)$ http://www.example.com/?dwnld_file=server1/$1 [QSA,L]

В приведенном выше коде мы перенаправляем все файлы в основной домен, за исключением случаев, когда установлен параметр post . Например, http://server1.example.com/file.pdf будет перенаправлен на http://www.example.com/?dwnld_file=server1/file.pdf. Здесь server1 - это имя вашего субдомена, чтобы определить, если несколько субдоменов.

В состоянии перезаписи - RewriteCond %{QUERY_STRING} !key=(FgTyUeL), key и его значение FgTyUeL должны быть конфиденциальными и не стесняйтесь переходить на более сложные строки. Мы будем использовать это для доступа к файлу в WordPress.

Шаг 2:

Добавьте их в 'functions.php' вашей темы основной домен .

/* init hook to check whether user logged-in and pass to download function */
add_action( 'init', 'file_init' );
function file_init() {
    if ($_REQUEST[ 'dwnld_file' ] != '') {
        if ( ! is_user_logged_in() ) { // if not logged-in
            auth_redirect(); //redirect to login page
            // wp_redirect( 'http://www.example.com/login' ); // or some other page
            exit;
        }
        else {
            $spliturl = explode("/",$_REQUEST[ 'dwnld_file' ]);
            $originalurl = "http://".$spliturl[0].".example.com/".substr($_REQUEST[ 'dwnld_file' ], strpos($_REQUEST[ 'dwnld_file' ], "/") + 1);                
            check_download_file( $originalurl ); // if logged-in pass file to download
        }
    }
}

/* function to download file */
function check_download_file( $url ) {
    $key='?key=FgTyUeL'; // secure post key same as .htaccess
    $file = basename($url);
    $mime = wp_check_filetype( $file ); 

    if( false === $mime[ 'type' ] && function_exists( 'mime_content_type' ) )
        $mime[ 'type' ] = mime_content_type( $file );

    if( $mime[ 'type' ] )
    {           
        set_time_limit(0);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url.$key);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        $curl_response = curl_exec($ch);

        curl_close($ch);
        header('Expires: 0'); // no cache
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
        header('Cache-Control: private', false);
        header('Content-Type: application/force-download');
        header('Content-Disposition: attachment; filename="' . basename($url) . '"');
        header('Content-Transfer-Encoding: binary');
        header('Content-Length: ' . strlen($curl_response)); // provide file size
        header('Connection: close');
        echo $curl_response;
        die();            
    }
}

Вышеуказанные функции говорят сами за себя - мы проверяем аутентификацию WordPress и, если пользователь вошел в систему, мы добавим безопасный ключ и загрузим файл, используя cURL. Обратите внимание, что безопасный ключ должен совпадать с ключом в файле .htaccess вашего домена (ов).

Приведенная выше логика будет работать, если файл находится в любой папке вашего субдомена и даже в разных доменах (но должен быть общедоступным).

0 голосов
/ 30 августа 2018

Поместите защищенные файлы в личную папку за пределами общедоступной области вашего веб-сайта. Затем создайте страницу загрузки, которая берет имя файла в URL или что-то еще. Затем на этой странице выполните проверку подлинности:

is_user_logged_in() ||  auth_redirect();
// open file
// send headers
// echo contents
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...