Làm cách nào để hạn chế tải xuống tệp đính kèm cho một người dùng cụ thể?


12

Tôi có một trường hợp sử dụng rất cụ thể trong đó trang web được xây dựng cho một luật sư và mỗi khách hàng của anh ta có thể đăng nhập vào page trang / cổng thông tin cụ thể của riêng họ (loại bài đăng tùy chỉnh) mà không có khả năng truy cập wp-admin, v.v. (Tôi đã tạo tất cả đăng nhập / đăng ký / trang chỉnh sửa hồ sơ ở mặt trước). Trong trang / cổng thông tin này, luật sư sẽ để lại tin nhắn và tệp cho khách hàng tải xuống , theo lý thuyết, một khách hàng có thể đoán (hoặc nếu có kiến ​​thức về các tệp của khách hàng khác) và sau đó tải xuống một vấn đề về quyền riêng tư / bảo mật / tài liệu bí mật, vv

Tôi đang tìm ý tưởng / khái niệm cho một giải pháp, suy nghĩ ban đầu của tôi là có điểm liên kết tải xuống tới một số download.php gửi id tệp đính kèm, id người dùng, id trang / cổng thông tin và xử lý ở đầu kia. .

bạn nghĩ sao? Tôi đang đi đúng hướng hay cách tiếp cận này còn thiếu sót?

Cảm ơn!


Bạn đã tìm thấy một giải pháp cho điều này?
brasofilo

@brasofilo, không ..
Amit

Câu trả lời:


6

Điều cần phải xảy ra là bạn cần proxy yêu cầu tải xuống cho các loại tệp bạn muốn thông qua WordPress. Giả sử bạn sẽ hạn chế quyền truy cập vào các tệp ".doc".

1. Xác định một biến truy vấn cho biết tệp được yêu cầu

function add_get_file_query_var( $vars ) {
    $vars[] = 'get_file';
    return $vars;
}
add_filter( 'query_vars', 'add_get_file_query_var' );

2. Cập nhật .htaccess để chuyển tiếp yêu cầu cho các tệp bị hạn chế vào WordPress

Điều này sẽ nắm bắt các yêu cầu đến các tệp bạn muốn hạn chế và gửi lại cho WordPress bằng cách sử dụng biến truy vấn tùy chỉnh ở trên. Chèn quy tắc sau trước các RewriteConddòng.

RewriteRule ^wp-content/uploads/(.*\.docx)$ /index.php?get_file=$1

3. Chụp tên tệp được yêu cầu trong biến truy vấn tùy chỉnh; và xác minh quyền truy cập vào tệp:

function intercept_file_request( $wp ) {
    if( !isset( $wp->query_vars['get_file'] ) )
        return;

    global $wpdb, $current_user;

    // Find attachment entry for this file in the database:
    $query = $wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE guid='%s'", $_SERVER['REQUEST_URI'] );
    $attachment_id = $wpdb->get_var( $query );

    // No attachment found. 404 error.  
    if( !$attachment_id ) {
        $wp->query_vars['error'] = '404';
        return;
    }

    // Get post from database 
    $file_post = get_post( $attachment_id );
    $file_path = get_attached_file( $attachment_id );

    if( !$file_post || !$file_path || !file_exists( $file_path ) ) {
        $wp->query_vars['error'] = '404';
        return;
    }

    // Logic for validating current user's access to this file...
    // Option A: check for user capability
    if( !current_user_can( 'required_capability' ) ) {
        $wp->query_vars['error'] = '404';
        return;
    }

    // Option B: check against current user
    if( $current_user->user_login == "authorized_user" ) {
        $wp->query_vars['error'] = '404';
        return;
    }

    // Everything checks out, user can see this file. Simulate headers and go:
    header( 'Content-Type: ' . $file_post->post_mime_type );
    header( 'Content-Dispositon: attachment; filename="'. basename( $file_path ) .'"' );
    header( 'Content-Length: ' . filesize( $file_path ) );

    echo file_get_contents( $file_path );
    die(0);
}
add_action( 'wp', 'intercept_file_request' );

NB này giải pháp công trình cho đơn trang web cài đặt chỉ ! Điều này là do WordPress MU đã chuyển tiếp các yêu cầu tệp được tải lên trong các trang web phụ thông qua wp-includes/ms-files.php. Cũng có một giải pháp cho WordPress MU, nhưng nó liên quan nhiều hơn một chút.


Xin chào, tôi không thấy rằng bạn móc chức năng này theo từng bước intercept_file_requesthoặc được gọi ở bất cứ đâu, làm thế nào để chức năng đó bị sa thải?
Bobz

Điểm hay, nó nên được nối vào wp, tôi đã cập nhật ví dụ.
Bendoh

3

Gần đây tôi đã có một vấn đề liên quan và đã viết bài viết này về nó .

Tôi sẽ cho rằng các phần tải xuống được tải lên thông qua xử lý phương tiện của WordPress - hoặc nếu không, bạn có ID đính kèm để tải xuống.

Đề cương giải pháp

  • Làm cho thư mục tải lên 'an toàn' (Theo nghĩa này tôi chỉ có nghĩa là sử dụng .htaccessđể chặn mọi nỗ lực truy cập trực tiếp các tệp trong thư mục tải lên (hoặc thư mục con của chúng) - ví dụ: thông qua mysite.com/wp-content/uploads/conf/2012/09/myconfidentialfile.pdf)
  • Tạo liên kết tải xuống bao gồm ID tệp đính kèm - điều này đi qua WordPress để kiểm tra quyền của người dùng để xem tệp đính kèm cho phép / từ chối quyền truy cập.

Hãy cẩn thận

  • Điều này làm cho việc sử dụng .htaccessđể cung cấp bảo mật . Nếu điều này không khả dụng / bật (ví dụ máy chủ nginx), thì bạn sẽ không nhận được nhiều bảo mật. Bạn có thể ngăn người dùng duyệt thư mục uplods. Nhưng truy cập trực tiếp sẽ làm việc.
  • Theo như trên. Điều này không nên được sử dụng trong phân phối nếu bạn yêu cầu bảo mật tuyệt đối . Sẽ ổn nếu thiết lập cụ thể của bạn hoạt động - nhưng nói chung, nó không thể được đảm bảo. Bài viết liên kết của tôi là một phần cố gắng để giải quyết điều này.
  • Bạn sẽ mất hình thu nhỏ . Chặn truy cập trực tiếp vào một thư mục hoặc thư mục con sẽ có nghĩa là hình thu nhỏ của các tệp trong thư mục đó không thể được xem. Bài viết liên kết của tôi là một phần cố gắng để giải quyết điều này.

Chặn truy cập trực tiếp

Để thực hiện việc này trong thư mục tải lên của bạn (hoặc thư mục con - tất cả tài liệu bí mật phải nằm ở bất kỳ độ sâu nào trong thư mục này). Đặt một .htaccesstệp với các mục sau:

Order Deny,Allow
Deny from all

Sau đây tôi giả sử rằng bạn sẽ đính kèm tài liệu bí mật vào loại bài 'khách hàng'. Bất kỳ phương tiện nào được tải lên trên trang chỉnh sửa máy khách sẽ được lưu trữ trong uploads/conf/thư mục

Chức năng thiết lập thư mục tải lên được bảo vệ

function wpse26342_setup_uploads_dir(){

    $wp_upload_dir = wp_upload_dir();
    $protected_folder = trailingslashit($wp_upload_dir['basedir']) . 'conf';    

    // Do not allow direct access to files in protected folder
    // Add rules to /uploads/conf/.htacess
    $rules = "Order Deny,Allow\n";
    $rules .= "Deny from all";

    if( ! @file_get_contents( trailingslashit($protected_folder).'.htaccess' ) ) {
            //Protected directory doesn't exist - create it.
        wp_mkdir_p( $protected_folder);
    }
    @file_put_contents( trailingslashit($protected_folder).'.htaccess', $rules );

     //Optional add blank index.php file to each sub-folder of protected folder.
}

Tải lên tài liệu mật

   /**
    * Checks if content is being uploaded on the client edit-page
    * Calls a function to ensure the protected file has the .htaccess rules
    * Filters the upload destination to the protected file
    */
    add_action('admin_init', 'wpse26342_maybe_change_uploads_dir', 999);
    function wpse26342_maybe_change_uploads_dir() {
        global $pagenow;

        if ( ! empty( $_POST['post_id'] ) && ( 'async-upload.php' == $pagenow || 'media-upload.php' == $pagenow ) ) {
                if ( 'client' == get_post_type( $_REQUEST['post_id'] ) ) {
                       //Uploading content on the edit-client page

                       //Make sure uploads directory is protected
                       wpse26342_setup_uploads_dir();

                       //Change the destination of the uploaded file to protected directory.
                       add_filter( 'upload_dir', 'wpse26342_set_uploads_dir' );
                }
        }

    }

Làm xong việc đó, nội dung được tải lên sẽ ở bên trong uploads/confvà cố gắng truy cập trực tiếp vào nó bằng trình duyệt của bạn sẽ không hoạt động.

Đang tải xuống nội dung

Điều này thật dễ dàng. Url tải xuống có thể là một cái gì đó www.site.com?wpse26342download=5(trong đó 5 là ID đính kèm của nội dung được tải lên). Chúng tôi sử dụng điều này để xác định tệp đính kèm, kiểm tra quyền của người dùng hiện tại và cho phép họ tải xuống.

Đầu tiên, thiết lập biến truy vấn

/**
 * Adds wpse26342download to the public query variables
 * This is used for the public download url
 */
add_action('query_vars','wpse26342_add_download_qv');
function wpse26342_add_download_qv( $qv ){
    $qv[] = 'wpse26342download';
    return $qv;
}}

Bây giờ hãy thiết lập trình nghe để (có thể) kích hoạt tải xuống ...

add_action('request','wpse26342_trigger_download');
function wpse26342_trigger_download( $query_vars ){

        //Only continue if the query variable set and user is logged in...
    if( !empty($query_vars['wpse26342download']) && is_user_logged_in() ){

        //Get attachment download path
        $attachment = (int) $query_vars['wpse26342download'];
        $file = get_attached_file($attachment);

        if( !$file )
             return;

        //Check if user has permission to download. If not abort.       
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename='.basename($file));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file));

        ob_clean();
        flush();
        readfile($file);
        exit();
    }
    return $query_vars;
}

Nhận xét cuối cùng

Đoạn mã trên có thể chứa lỗi / lỗi cú pháp và chưa được kiểm tra, và bạn tự chịu rủi ro khi sử dụng nó :).

Url tải xuống có thể được 'chỉnh sửa' bằng cách viết lại. Như đã nêu trong các bình luận, bạn có thể thêm một khoảng trống index.phpbên trong mỗi đứa trẻ của thư mục được bảo vệ để ngăn chặn việc duyệt - nhưng dù sao thì điều này cũng nên được ngăn chặn bởi các .htaccessquy tắc.

Một phương pháp an toàn hơn sẽ là lưu trữ các tệp công khai bên ngoài một thư mục công cộng. Hoặc trên một dịch vụ bên ngoài như Amazon S3. Để sau này, bạn sẽ cần tạo một url hợp lệ để tìm nạp tệp từ Amazon (sử dụng khóa riêng của bạn). Cả hai điều này đòi hỏi một mức độ tin cậy nhất định đối với dịch vụ Máy chủ / bên thứ ba của bạn.

Tôi sẽ cảnh giác về việc sử dụng bất kỳ plugin nào đề xuất họ cung cấp 'tải xuống được bảo vệ'. Tôi đã không tìm thấy bất kỳ cung cấp bảo mật đủ tốt. Xin vui lòng không cảnh báo về giải pháp này - và tôi hoan nghênh mọi đề xuất hoặc chỉ trích.


1

Có thể, bạn có thể đã biết thủ thuật này, Mã này sẽ kiểm tra tên người dùng đã đăng nhập hiện tại và nếu nó khớp với nó sẽ hiển thị liên kết tải xuống tệp đó, nếu không nó sẽ không hiển thị bất cứ điều gì.

đây là mã:

<?php 
    global $current_user;
    get_currentuserinfo();

    if ( 'username' == $current_user->user_login ) {
        echo 'Download Link';
    } else {
        // nothing
    }
?>

Tuy nhiên, đây sẽ không phải là một cách tiếp cận tốt, vì các tệp được lưu trữ trên máy chủ, bất kỳ ai có liên kết đều có thể tải xuống tệp đó.


0

Tôi cho rằng thông tin này là bí mật và do đó, ngoài việc ẩn các liên kết đến các tệp bạn sẽ thực sự khiến chúng không thể truy cập được hoàn toàn cho bất kỳ ai trên web, ngay cả khi họ đoán URL, trừ khi người dùng đó có quyền tải xuống rõ ràng Tập tài liệu.

Xem xét việc lưu trữ các tệp trên Amazon S3 một cách an toàn và sau đó cung cấp các URL được ký trước (giới hạn thời gian) cho tệp với điều kiện kiểm tra bảo mật chính xác đã được thỏa mãn (tức là người dùng đã đăng nhập vào trang web của bạn và họ nói họ là ai).

Có một SDK AWS rất tốt giúp nó rất dễ dàng để làm điều này.

Thay vào đó, những gì bạn sẽ cần nghiên cứu là làm thế nào để gửi các tệp được tải lên thông qua giao diện tải lên WP vào S3, thay vào đó, hãy xây dựng trình tải lên của riêng bạn .

Một lựa chọn khác sẽ là quá nhìn vào mã của thương mại điện tử WP . Họ cung cấp tải xuống an toàn các tệp phần mềm (ví dụ MP3). Tôi tin rằng các tệp được chuyển đổi thành băm với khóa mã hóa được tạo cho mỗi người dùng khi mua. Điều này sẽ mất một số giải mã để xem nó hoạt động như thế nào, nhưng quá trình sẽ không phải là duy nhất cho plugin này để các ví dụ khác sẽ có sẵn (ở đâu đó).


0

Tôi nghĩ rằng mã hóa các tập tin là cách để đi như câu trả lời ở trên. Có một plugin trên Wordpress.org cho phép bạn bảo vệ các phần tải xuống. http://wordpress.org/extend/plugins/doad-protect/ Bạn cũng có thể sử dụng dịch vụ amazons hoặc google drive. Có rất nhiều dịch vụ cung cấp tải xuống được bảo vệ như hộp thả.


bảo mật thông qua che khuất là một cách tiếp cận xấu. bất cứ ai cũng có thể xem yêu cầu http và nhận url theo cách này.
mulllhausen
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.