Bagaimana cara Melindungi Upload, jika Pengguna tidak Masuk?

80

Saya menggunakan wordpress untuk situs pribadi tempat pengguna mengunggah file. Saya menggunakan "Private WordPress" untuk mencegah akses ke situs jika pengguna tidak masuk.

Saya ingin melakukan hal yang sama terhadap file yang diunggah dalam folder unggahan.

Jadi, jika pengguna yang tidak masuk mereka tidak akan dapat mengakses: https://xxxxxxx.com/wp-content/uploads/2011/12/xxxxxxx.pdf jika mereka mencoba mengakses tetapi mereka tidak login maka mereka harus diarahkan ke halaman login misalnya.

Saya menemukan sebuah plugin yang disebut file pribadi tetapi terakhir kali diperbarui pada tahun 2009 dan sepertinya tidak berfungsi pada wordpress saya.

Adakah yang tahu metode apa pun? Metode hotlinking akan cukup untuk melindungi ini?

Saya juga menemukan metode ini:

# 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

Tetapi, apakah ada pengguna yang meniru cookie yang dapat melewatkan ini dengan benar? Salam

chifliiiii
sumber
1
Ada alasan mengapa Anda tidak dapat menggunakan direktori unggah yang berbeda, seperti yang ada di luar root situs?
onetrickpony
Tidak juga, tetapi saya sudah punya banyak file yang dilampirkan ke posting di direktori itu, saya tidak keberatan bergerak di sekitar jika saya dapat menemukan solusi yang tepat
chifliiiii

Jawaban:

86

Hanya memeriksa apakah ada cookie, tidak banyak perlindungan yang ketat.

Untuk mendapatkan perlindungan yang lebih kuat, Anda dapat meneruskan atau "proxy" semua permintaan ke folder yang diunggah (contoh uploadsdalam contoh berikut) melalui skrip php:

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

Semua permintaan untuk file yang diunggah (yang termasuk gambar dalam posting) akan pergi ke dl-file.phpyang kemudian dapat melakukan verifikasi jika pengguna masuk atau tidak.

Jika pengguna tidak masuk, formulir masuk situs Anda akan ditampilkan. Setelah pengguna masuk, ia akan diarahkan kembali ke file dan dapat mengunduhnya sekarang.

Teladandl-file.php .

Hal serupa dapat ditemukan di \wp-includes\ms-files.phpinstalasi wordpress Anda, tetapi itu untuk multisite dan tanpa login login dan redirect.

Bergantung pada seberapa banyak lalu lintas yang Anda miliki, mungkin lebih baik untuk mengintegrasikan ini dengan server Anda, misalnya, X-Accel-Redirectatau X-Sendfileheader.

hakre
sumber
1
bagaimana Anda menyesuaikan dl-file.php jika saya ingin menyimpan file ke subdirektori seperti wp-content / uploads / secure?
Ini adalah satu-satunya solusi yang benar-benar aman. Hal lain yang dapat Anda temukan di web, seperti memeriksa tajuk rujukan, memeriksa cookie, melarang daftar direktori, adalah ukuran setengah karena Anda dapat dengan mudah memalsukan header permintaan HTTP untuk mengatasinya.
Luke
Guys..this sepertinya solusi sempurna bagi saya .... masalahnya adalah, saya menggunakan PDFJS dari Mozilla untuk mengakses beberapa PDF dari folder unggah, dan PDFJS menggunakan header sebagian konten untuk mendapatkan hanya halaman yang diinginkan .. .jadi solusi ini bukan solusi bagi saya. ada saran ??
Otto Nascarella
@OttoNascarella: Permintaan Konten Sebagian ke PHP telah diselesaikan pada hari ini, ini tidak tergantung pada pertanyaan wordpress ini. Infact, pertanyaannya sudah cukup lama: Unduhan yang dapat dilanjutkan saat menggunakan PHP untuk mengirim file?
hakre
@hakre Bagaimana dengan beberapa gambar yang digunakan di halaman depan situs web dan setiap pengguna datang mengunjungi situs? Ini memberi saya 404 kesalahan jika saya tidak login.
Dhaval Panchal
14

Anda juga dapat menulis plugin menggunakan inithook dan get-value $_GET[ 'file' ];. Jika pengguna memiliki nilai get ini, lompati fungsi untuk memeriksa hak akses pada file: Misalnya dengan kotak centang di Kotak Meta.

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

fungsi 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();
}

Anda juga dapat menambahkan URL khusus untuk file melalui hook 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;
}
bueltge
sumber
Ini tidak berhasil di pihak saya ada yang tahu kenapa? Saya menyalin persis.
Ryan S
Perlindungan hanya bekerja pdf. ekstensi file lain tidak berfungsi seperti: doc, docx, jpg, dll ...
Patel
1

Jika Anda ingin pendekatan berbasis plugin untuk menyelesaikan masalah ini, berikut ini adalah solusi yang cukup bagus yang saya temukan (akhirnya):

  1. Instal plugin 'Unduh Monitor', tersedia di:
    https://wordpress.org/plugins/download-monitor/
  2. Di Dasbor WordPress, buka item menu 'Unduhan' yang baru dan tambahkan 'Unduhan' baru, seperti yang dijelaskan pada situs web dokumentasi plugin di sini: https://www.download-monitor.com/kb/adding-downloads/ . Catat kode pendek 'Unduh' yang disediakan untuk Anda (mis. Simpan ke Notepad). Perhatikan bahwa file tersebut disimpan/wp-content/uploads/dlm_uploads/
  3. Dalam metabox 'Opsi unduhan', tentukan 'Hanya anggota' (seperti yang didokumentasikan di sini https://www.download-monitor.com/kb/download-options/ ), dan klik 'Terbitkan'.
  4. Pada halaman yang Anda inginkan hanya unduhan Anggota yang muncul, tambahkan kode pendek yang Anda perhatikan pada langkah # 2, dan 'Terbitkan / Perbarui' halaman tersebut, seperti yang didokumentasikan di sini: https://www.download-monitor.com / kb / download kode pendek / . Anda dapat mengubah templat tautan unduhan seperti yang dijelaskan di sini https://www.download-monitor.com/kb/content-templates/ , atau membuat sendiri (mis. Untuk menghapus unduhan 'hitungan').
  5. Jelajahi halaman Anda, Anda akan melihat tautan unduhan (tetapi yang tidak mengungkapkan URL ke file unduhan). Jika Anda meramban ke halaman yang sama di jendela browser baru (atau jendela Penyamaran), Anda akan menemukan bahwa unduhan tidak lagi berfungsi.

Ini berarti bahwa siapa pun yang tidak masuk tidak dapat mengunduh file atau melihat URL asli ke file tersebut. Jika seandainya ada orang yang tidak berwenang mengetahui URL ke file tersebut, plugin tersebut juga akan menghentikan pengguna yang meramban URL file asli dengan memblokir akses ke /wp-content/uploads/dlm_uploads/folder tersebut.

Bonus: jika Anda melakukan ini untuk situs di mana Anda memerlukan pengguna untuk dapat login sebagai 'Anggota' saja (tetapi tidak memiliki izin WordPress seperti mengedit halaman atau menjadi Admin), instal plugin 'Anggota' https: // wordpress .org / plugins / members / , buat peran pengguna baru yang disebut 'Anggota', dan berikan kemampuan tunggal 'baca', buat Pengguna baru di WordPress, dan pastikan untuk memberi mereka peran 'Anggota'.

Jika Anda ingin melindungi konten halaman, plugin 'Anggota' menyediakan beberapa opsi, atau ada plugin lain di luar sana. Jika Anda ingin membuat tema halaman login agar Anggota terlihat lebih baik daripada formulir login default WordPress, gunakan sesuatu seperti 'Theme My Login': https://wordpress.org/plugins/theme-my-login/

Matty J
sumber
Proses yang saya jelaskan di atas juga dijelaskan di sini, walaupun seperti yang Anda lihat, tidak harus spesifik hanya dengan PDF: thedigitalcrowd.com/website-development/wordpress/…
Matty J