如果用户未登录,如何保护上传?

时间:2011-12-22 作者:chifliiiii

我使用WordPress作为一个私人网站,用户可以在这里上传文件。如果用户未登录,我使用“私有WordPress”阻止访问该网站。

我想对上传到uploads文件夹中的文件执行同样的操作。

因此,如果用户未登录,他们将无法访问:https://xxxxxxx.com/wp-content/uploads/2011/12/xxxxxxx.pdf如果他们试图访问,但他们没有被记录,那么他们应该被重定向到登录页面,例如。

我发现了一个名为private files的插件,但上次更新是在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的用户都可以通过此权限?当做

4 个回复
最合适的回答,由SO网友:hakre 整理而成

仅检查cookie是否存在并不是一种严格的保护。

为了获得更强的保护,您可以将所有请求传递或“代理”到上载的文件夹(示例uploads 在以下示例中)通过php脚本:

RewriteCond %{REQUEST_FILENAME} -s
RewriteRule ^wp-content/uploads/(.*)$ dl-file.php?file=$1 [QSA,L]
所有上传文件(包括帖子中的图像)的请求都将转到dl-file.php 然后可以验证用户是否登录。

如果用户未登录,将显示您的站点登录表单。用户登录后,将被重定向回该文件并可以立即下载。

Exemplary dl-file.php.

类似的内容可以在\\wp-includes\\ms-files.php 在您的wordpress安装中,但这是针对多站点的,并且没有登录检查和重定向。

根据您拥有的流量大小,最好将其与服务器更好地集成,例如:。X-Accel-RedirectX-Sendfile 标题。

SO网友:bueltge

两种方式,简单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();
}
您还可以通过挂钩为文件添加自定义URLgenerate_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> 容器,有三条规则可以执行以下操作:

检查请求是否针对任何文件检查是否缺少以开头的cookiewordpress_logged_in_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>

SO网友:Matty J

如果您希望使用基于插件的方法来解决此问题,我(最终)找到了一个相当好的解决方案:

安装“下载监视器”插件,网址:
https://wordpress.org/plugins/download-monitor/ https://www.download-monitor.com/kb/adding-downloads/.记下为您提供的“下载”快捷码(例如保存toNotepad)。请注意,文件保存在/wp-content/uploads/dlm_uploads/在“下载选项”元框中,指定“仅限成员”(如此处所述https://www.download-monitor.com/kb/download-options/), 然后单击“发布”在您只希望会员下载的页面上,添加您在步骤#2中注意到的短代码,并“发布/更新”页面,如下所述:https://www.download-monitor.com/kb/shortcode-download/. 您可以按此处所述更改下载链接模板https://www.download-monitor.com/kb/content-templates/, 或者创建自己的(例如,要删除下载“count”)

  • 浏览您的页面,您应该会看到一个下载链接(但不会显示下载文件的URL)。如果在新的浏览器窗口(或匿名窗口)中浏览到同一页面,您应该会发现下载不再有效
  • 这意味着任何未登录的人都无法下载文件或查看文件的真实URL。如果有未经授权的人找到了文件的URL,插件还会阻止用户访问/wp-content/uploads/dlm_uploads/ 文件夹

    奖励:如果你这样做是为了一个网站,你需要用户只能以“成员”身份登录(但没有WordPress权限,如页面编辑或管理员),请安装“成员”插件https://wordpress.org/plugins/members/, 创建一个名为“Member”的新用户角色,并为其提供“read”的单一功能,在WordPress中创建一个新用户,并确保为其提供“Member”角色。

    如果你想保护页面的内容,“成员”插件提供了一些选项,或者还有其他插件。如果您想为成员设置登录页面主题,使其看起来比WordPress默认登录表单更好,请使用类似“设置我的登录主题”的内容:https://wordpress.org/plugins/theme-my-login/

    SO网友:Waleed

    如何使用基于插件的方法来解决此问题,我发现创建了一个WP插件来解决此问题:

    阻止文件/文件夹访问:https://wordpress.org/plugins/prevent-file-access/

    结束