사용자가 로그인하지 않은 경우 업로드를 보호하는 방법은 무엇입니까?


79

사용자가 파일을 업로드하는 개인 사이트에 워드 프레스를 사용합니다. 사용자가 로그인하지 않은 경우 "비공개 WordPress"를 사용하여 사이트에 액세스하지 못하게합니다.

업로드 폴더에 업로드 된 파일에 대해서도 동일하게 수행하고 싶습니다.

그들은 로그인하지 않은 그 사용자가 액세스 할 수 실 거예요 그래서 경우 : https://xxxxxxx.com/wp-content/uploads/2011/12/xxxxxxx.pdf를 가 액세스하려고하면하지만 다음 기록되지 않습니다 그들은해야 예를 들어 로그인 페이지로 리디렉션됩니다.

개인 파일이라는 플러그인을 찾았지만 마지막으로 업데이트 된 시간은 2009 년이며 내 워드 프레스에서 작동하지 않는 것 같습니다.

누구든지 어떤 방법을 알고 있습니까? 핫 링크 방식으로이를 보호하기에 충분합니까?

나는 또한이 방법을 발견했다 :

# 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

그러나 쿠키를 복제하는 사용자가이 권한을 전달할 수 있습니까? 문안 인사


1
사이트 루트 외부와 같은 다른 업로드 디렉토리를 사용할 수없는 이유는 무엇입니까?
onetrickpony

아니 정말하지만 난 이미 디렉토리에있는 게시물에 첨부 된 파일의 톤, 내가 적절한 솔루션을 찾을 수 있다면 모든 주위 이동에 마음을 그나마 가지고
chifliiiii

답변:


86

쿠키가 존재하는지 확인하는 것만으로는 엄격한 보호가되지 않습니다.

보다 강력한 보호 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워드 프레스 설치 에서 비슷한 것을 찾을 수 있지만, 다중 사이트 용이며 로그인 확인 및 리디렉션이 없습니다.

트래픽이 얼마나 많은지에 따라 서버 X-Accel-RedirectX-Sendfile헤더 와 같은 서버에 더 잘 통합하는 것이 좋습니다 .


1
wp-content / uploads / secure와 같은 하위 디렉토리에 파일을 저장하려면 dl-file.php를 어떻게 조정합니까?

이것이 유일하게 안전한 솔루션입니다. 웹에서 참조 헤더 확인, 쿠키 확인, 디렉토리 목록 허용 안 함 등 웹에서 찾을 수있는 것은 HTTP 요청 헤더를 쉽게 스푸핑하여 해결할 수 있기 때문에 절반 정도입니다.
누가 복음

Guys .. 이것은 나에게 완벽한 솔루션처럼 보였습니다 .... 문제는 Mozilla의 PDFJS를 사용하여 업로드 폴더에서 일부 PDF에 액세스하고 있으며 PDFJS는 부분 컨텐츠 헤더를 사용하여 관심있는 페이지 만 가져옵니다 .. . 그래서이 솔루션은 나에게 아무런 도움이되지 않습니다. 어떤 제안?
오토 나스카 렐라

@OttoNascarella : PHP에 대한 부분 컨텐츠 요청이 오늘부터 해결되었습니다. 이것은이 워드 프레스 질문과 무관합니다. 실제로, 질문은 이미 오래되었습니다 : PHP를 사용하여 파일을 보낼 때 재개 가능한 다운로드?
hakre

@hakre 웹 사이트 첫 페이지에 사용 된 이미지 중 일부는 사용자가 사이트를 방문하게됩니까? 로그인하지 않으면 404 오류가 발생합니다.
Dhaval Panchal

14

init후크 및 get-value를 사용하여 플러그인을 작성할 수도 있습니다 $_GET[ 'file' ];. 사용자에게이 Get-Value가 있으면 파일에 액세스 할 수있는 권한을 확인하는 기능으로 이동하십시오 (예 : 메타 박스의 확인란 사용).

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

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;
}

이것은 내 편에서 효과가 없었습니다. 정확하게 복사합니다.
Ryan S

보호 작업 만 pdf. 다른 파일 확장자가 다음과 같이 작동하지 않습니다 : doc, docx, jpg and etc ...
Patel

1

이 문제를 해결하기 위해 플러그인 기반 접근 방식을 원한다면 (최종적으로) 찾은 합리적으로 좋은 해결책이 있습니다.

  1. https://wordpress.org/plugins/download-monitor/ 에서 제공되는 플러그인 'Download Monitor'를 설치
    하십시오.
  2. 플러그인 문서 웹 사이트 ( https://www.download-monitor.com/kb/adding-downloads/) 에 설명 된대로 WordPress 대시 보드에서 새 '다운로드'메뉴 항목으로 이동하여 새 '다운로드'를 추가 하십시오 . 제공된 '다운로드'단축 코드를 기록해 두십시오 (예 : 메모장에 저장). 파일이 저장됩니다/wp-content/uploads/dlm_uploads/
  3. 'Download options'메타 박스에서 'Members only'(여기서 https://www.download-monitor.com/kb/download-options/ 참조 )를 지정하고 'Publish'를 클릭하십시오.
  4. 회원 전용 다운로드 만 표시하려는 페이지에서 2 단계에서 적어 둔 단축 코드를 추가하고 여기에 설명 된대로 페이지를 '게시 / 업데이트'하십시오 ( https://www.download-monitor.com). / / 단축 코드 - 다운로드 / 킬로바이트 . 여기에 설명 된대로 다운로드 링크 템플릿을 변경 하거나 https://www.download-monitor.com/kb/content-templates/ 를 만들거나 직접 만들 수 있습니다 (예 : Download 'count'제거).
  5. 페이지를 탐색하면 다운로드 링크가 표시되지만 다운로드 파일의 URL은 표시되지 않습니다. 새 브라우저 창 (또는 시크릿 창)에서 동일한 페이지를 탐색하면 다운로드가 더 이상 작동하지 않는 것을 알 수 있습니다.

즉, 로그인하지 않은 사람은 파일을 다운로드하거나 파일의 실제 URL을 볼 수 없습니다. 누군가가 파일에 대한 URL을 무단으로 알아 낸 경우, 플러그인은 /wp-content/uploads/dlm_uploads/폴더에 대한 액세스를 차단하여 사용자가 실제 파일 URL을 탐색하지 못하게 합니다.

보너스 : 사용자가 '회원'으로 만 로그인 할 수 있어야하지만 (페이지 편집 또는 관리자와 같은 WordPress 권한이없는 사이트)이 작업을 수행하는 경우 '회원'플러그인 https : // wordpress를 설치하십시오 .org / plugins / members / , '회원'이라는 새 사용자 역할을 만들고 '읽기'의 단일 기능을 제공하고 WordPress에서 새 사용자를 만들고 '회원'역할을 부여하십시오.

페이지의 내용을 보호하려면 '멤버'플러그인에서 몇 가지 옵션을 제공하거나 다른 플러그인이 있습니다. 회원이 로그인 페이지를 테마로하여 WordPress 기본 로그인 양식보다 더 좋아 보이게하려면 'Theme My Login'과 같은 것을 사용 하십시오 : https://wordpress.org/plugins/theme-my-login/


위에서 설명한 프로세스도 여기에 설명되어 있지만 PDF에만 국한되지 않아도됩니다. thedigitalcrowd.com/website-development/wordpress/…
Matty J
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.