Как защитить загрузки, если Пользователь не вошел в систему?


Я использую WordPress для частного сайта, где пользователи загружают файлы. Я использую "Частный WordPress", чтобы запретить доступ к сайту, если пользователь не вошел в систему.

Я хотел бы сделать то же самое с файлами, загруженными в папку загрузки.

Таким образом, если пользователь не вошел в систему, он не сможет получить доступ к : https://xxxxxxx.com/wp-content/uploads/2011/12/xxxxxxx.pdf если они пытаются получить доступ, но не вошли в систему, их следует перенаправить на вход страница, например.

Я нашел плагин под названием "Личные файлы", но в последний раз он обновлялся в 2009 году, и, похоже, он не работает на моем WordPress.

Кто-нибудь знает какой-нибудь метод? Метода горячей ссылки будет достаточно для защиты этого?

Я также нашел этот метод:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^.*uploads/private/.*
RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in.*$ [NC]
RewriteRule . /index.php [R,L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Но тогда любой пользователь, который копирует файл cookie, может передать это право? С уважением

Author: butlerblog, 2011-12-22

4 answers

Только проверка того, существует ли файл cookie, не является строгой защитой.

Чтобы получить более надежную защиту, вы можете передавать или "проксировать" все запросы в загруженную папку (пример uploads в следующем примере) с помощью php-скрипта:

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

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

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

Образцовый dl-file.php.

Нечто подобное можно найти в \wp-includes\ms-files.php в вашей установке wordpress, но это для нескольких сайтов и без проверки входа и перенаправления.

В зависимости от того, сколько у вас трафика, было бы разумно лучше интегрировать это с вашим сервером, например, заголовки X-Accel-Redirect или X-Sendfile.

 101
Author: hakre, 2012-01-02 21:50:59

Два способа, простых в 2. с помощью правила apache или в 1. с помощью пользовательского кода в плагине.

1. Плагин

Вы можете написать плагин, используя хук init и get-значение $_GET[ 'file' ];. Если у пользователя есть это значение get, перейдите в функцию, чтобы проверить права доступа к файлам: например, с помощью флажка внутри мета-поля.

add_action( 'init', 'fb_init' );
function fb_init() {
    // this in a function for init-hook
    if ( '' != $_GET[ 'file' ] ) {
        fb_get_file( $_GET[ 'file' ] );
    }
}

Функция fb_get_file()

function fb_get_file( $file ) {

    $upload     = wp_upload_dir();
    $the_file   = $file; 
    $file       = $upload[ 'basedir' ] . '/' . $file;
    if ( !is_file( $file ) ) {
        status_header( 404 );
        die( '404 &#8212; File not found.' );
    }
    else {
        $image = get_posts( array( 'post_type' => 'attachment', 'meta_query' => array( array( 'key' => '_wp_attached_file', 'value' => $the_file ) ) ) );
        if ( 0 < count( $image ) && 0 < $image[0] -> post_parent ) { // attachment found and parent available
            if ( post_password_required( $image[0] -> post_parent ) ) { // password for the post is not available
                wp_die( get_the_password_form() );// show the password form 
            }
            $status = get_post_meta( $image[0] -> post_parent, '_inpsyde_protect_content', true );

            if ( 1 == $status &&  !is_user_logged_in() ) {
                wp_redirect( wp_login_url( $upload[ 'baseurl' ] . '/' . $the_file ) );
                die();
            }
        }
        else {
            // not a normal attachment check for thumbnail
            $filename   = pathinfo( $the_file );
            $images     = get_posts( array( 'post_type' => 'attachment', 'meta_query' => array( array( 'key' => '_wp_attachment_metadata', 'compare' => 'LIKE', 'value' => $filename[ 'filename' ] . '.' . $filename[ 'extension' ] ) ) ) );
            if ( 0 < count( $images ) ) {
                foreach ( $images as $SINGLEimage ) {
                    $meta = wp_get_attachment_metadata( $SINGLEimage -> ID );
                    if ( 0 < count( $meta[ 'sizes' ] ) ) {
                        $filepath   = pathinfo( $meta[ 'file' ] );
                        if ( $filepath[ 'dirname' ] == $filename[ 'dirname' ] ) {// current path of the thumbnail
                            foreach ( $meta[ 'sizes' ] as $SINGLEsize ) {
                                if ( $filename[ 'filename' ] . '.' . $filename[ 'extension' ] == $SINGLEsize[ 'file' ] ) {
                                    if ( post_password_required( $SINGLEimage -> post_parent ) ) { // password for the post is not available
                                        wp_die( get_the_password_form() );// show the password form 
                                    }
                                    die('dD');
                                    $status = get_post_meta( $SINGLEimage -> post_parent, '_inpsyde_protect_content', true );

                                    if ( 1 == $status &&  !is_user_logged_in() ) {
                                        wp_redirect( wp_login_url( $upload[ 'baseurl' ] . '/' . $the_file ) );
                                        die();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    $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 );
    die();
}

Вы также можете добавить пользовательский URL-адрес для файлов с помощью крючка generate_rewrite_rules

add_filter( 'generate_rewrite_rules', 'fb_generate_rewrite_rules' );

function fb_generate_rewrite_rules( $wprewrite ) {
        $upload = wp_upload_dir();
        $path = str_replace( site_url( '/' ), '', $upload[ 'baseurl' ] );
        $wprewrite -> non_wp_rules = array( $path . '/(.*)' => 'index.php?file=$1' );
        return $wprewrite;
}

2. Apache проверяет наличие файла cookie

Оставьте новый файл .htaccess внутри каталога /wp-content/uploads/. Или другой определенный каталог для загрузок.

Как это работает

Внутри контейнеров <IfModule> есть три правила, которые выполняют следующие действия:

  1. Проверьте, не запрашивается ли какой-либо файл
  2. Проверьте отсутствие файла cookie, который начинается с wordpress_logged_in_
  3. Если эти условия будут выполнены, запрос файла будет отклонен через 403 "Запрещенный" ответ

Хитрость здесь заключается в шаге 2, затем проверьте отсутствие файла cookie, который начинается с wordpress_logged_in_. Когда пользователь входит в систему, WordPress добавляет файл cookie в ваш браузер, который выглядит следующим образом:

wordpress_logged_in_1234567890abcdefghijklmnopqrstuvwxyz

Пример правила с проверкой типа файла

# require login for media files
<IfModule mod_rewrite.c>
    RewriteCond %{REQUEST_FILENAME} (.*)
    RewriteCond %{HTTP_COOKIE} !wordpress_logged_in_([a-zA-Z0-9_]*) [NC]
    RewriteRule .* - [F,L]
</IfModule>
 19
Author: bueltge, 2021-02-03 10:16:17

Если вам нужен подход к решению этой проблемы на основе плагинов, вот достаточно хорошее решение, которое я (наконец) нашел:

  1. Установите плагин "Монитор загрузки", доступный по адресу:
    https://wordpress.org/plugins/download-monitor/
  2. На панели управления WordPress перейдите в пункт меню "Новые загрузки" и добавьте новую "Загрузку", как описано на веб-сайте документации по плагинам здесь: https://www.download-monitor.com/kb/adding-downloads /. Обратите внимание на предоставленный вам шорткод "Загрузить" (например, сохранить в Блокнот). Обратите внимание, что файл сохраняется в /wp-content/uploads/dlm_uploads/
  3. В метабоксе "Параметры загрузки" укажите "Только для участников" (как описано здесь https://www.download-monitor.com/kb/download-options /) и нажмите "Опубликовать".
  4. На странице, которую вы хотите, чтобы загружали только участники, добавьте шорткод, который вы отметили на шаге № 2, и "Опубликовать/обновить" страницу, как описано здесь: https://www.download-monitor.com/kb/shortcode-download /. Вы можете изменить шаблон ссылки для загрузки, как описано здесь https://www.download-monitor.com/kb/content-templates /, или создайте свой собственный (например. чтобы удалить "счетчик загрузок")
  5. Перейдите на свою страницу, вы должны увидеть ссылку для загрузки (но которая не раскрывает URL-адрес загружаемого файла). Если вы перейдете на ту же страницу в новом окне браузера (или в окне инкогнито), вы должны обнаружить, что загрузка больше не работает.

Это означает, что любой, кто не вошел в систему, не может ни загрузить файл, ни увидеть реальный URL-адрес файла. Если в случае, если кто-то неавторизованный узнает URL-адрес файла, плагин также останавливает просмотр пользователями реального URL-адреса файла, блокируя доступ к папке /wp-content/uploads/dlm_uploads/.

Бонус: если вы делаете это для сайта, где вам нужно, чтобы пользователи могли входить в систему только как "Пользователи" (но у вас нет разрешений WordPress, таких как страница редактирование или быть администратором), установите плагин "Участники" https://wordpress.org/plugins/members /, создайте новую роль пользователя под названием "Участник" и предоставьте ей единственную возможность "читать", создайте нового пользователя в WordPress и обязательно дайте ему роль "Участник".

Если вы хотите защитить содержимое страниц, плагин "Участники" предоставляет некоторые опции или существуют другие плагины. Если вы хотите, чтобы тема страницы входа для пользователей выглядела лучше, чем по умолчанию в WordPress форма входа, используйте что-то вроде "Тема моего входа": https://wordpress.org/plugins/theme-my-login/

 2
Author: Matty J, 2017-04-13 09:09:36

Как насчет подхода к решению этой проблемы на основе плагинов, я нашел плагин WP, созданный для этого:

Запретить доступ к файлам/папкам: https://wordpress.org/plugins/prevent-file-access/

 0
Author: Waleed, 2021-01-08 14:28:32