¿Cómo proteger las cargas, si el usuario no ha iniciado sesión?

70

Uso wordpress para un sitio privado donde los usuarios cargan archivos. Utilizo "Private WordPress" para impedir el acceso al sitio si el usuario no ha iniciado sesión.

Me gustaría hacer lo mismo con los archivos cargados en la carpeta de subidas.

Entonces, si un usuario no ha iniciado sesión no podrá acceder a: enlace Si intentan acceder pero no están registrados, deben ser redirigidos a la página de inicio de sesión, por ejemplo.

Encontré un complemento llamado archivos privados, pero la última vez que lo actualicé fue en 2009 y parece que no funciona en mi wordpress.

¿Alguien sabe algún método? ¿El método de hotlinking será suficiente para proteger esto?

También encontré este método:

# 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

¿Pero entonces cualquier usuario que replique la cookie podría pasar este derecho? Saludos

    
pregunta chifliiiii 22.12.2011 - 17:46

3 respuestas

78

Solo comprobar si la cookie existe, no es una protección estricta.

Para obtener una protección más sólida, puede pasar o "hacer proxy" todas las solicitudes a la carpeta cargada (ejemplo uploads en el siguiente ejemplo) a través de un script php:

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

Todas las solicitudes de archivos cargados (que incluyen imágenes en publicaciones) irán a dl-file.php , que luego puede verificar si el usuario ha iniciado sesión o no.

Si el usuario no ha iniciado sesión, se mostrará el formulario de inicio de sesión de sus sitios. Una vez que el usuario haya iniciado sesión, será redirigida nuevamente al archivo y podrá descargarla ahora.

Ejemplar dl-file.php .

Se puede encontrar algo similar en \wp-includes\ms-files.php en su instalación de wordpress, pero esa es para multisitio y sin el control de inicio de sesión y las redirecciones.

Dependiendo de la cantidad de tráfico que tenga, podría ser conveniente integrar esto mejor con su servidor, por ejemplo. X-Accel-Redirect o X-Sendfile headers.

    
respondido por el hakre 02.01.2012 - 22:50
14

También puede escribir un complemento utilizando el gancho init y el valor de obtención $_GET[ 'file' ]; . Si el usuario tiene este valor, salte en una función para verificar los derechos de acceso a los archivos: por ejemplo, con una casilla de verificación en un Meta Box.

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

la función 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();
}

También puede agregar una URL personalizada para los archivos a través del gancho 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;
}
    
respondido por el bueltge 03.01.2012 - 11:20
1

Si desea un enfoque basado en complementos para resolver este problema, aquí hay una solución razonablemente buena que (finalmente) encontré:

  1. Instale el complemento 'Monitor de descarga', disponible en:
    enlace
  2. En el Panel de WordPress, vaya al nuevo elemento del menú 'Descargas' y agregue una nueva 'Descarga', como se describe en la documentación del complemento sitio web aquí: enlace . Tome nota del código abreviado de 'Descarga' que se le proporcionó (por ejemplo, guardar en Bloc). Tenga en cuenta que el archivo se guarda en /wp-content/uploads/dlm_uploads/
  3. En el metabox 'Opciones de descarga', especifique 'Solo miembros' (como se documenta aquí enlace ), y haga clic en 'Publicar'.
  4. En la página en la que desea que aparezcan los miembros que solo se descargan, agregue el shortcode del que tomó nota en el paso # 2 y 'Publique / actualice' la página, como se documenta aquí: enlace . Puede cambiar la plantilla de enlace de descarga como se describe aquí enlace , o crear la suya propia (por ejemplo, para eliminar la descarga 'cuenta')
  5. Vaya a su página; debería ver un enlace de descarga (pero que no revela la URL del archivo de descarga). Si navega a la misma página en una nueva ventana del navegador (o ventana de incógnito), debería encontrar que la descarga ya no funciona.

Esto significa que cualquiera que no haya iniciado sesión no puede descargar el archivo o ver la URL real del archivo. Si en el caso de que alguien no autorizado descubra la URL del archivo, el complemento también impide que los usuarios naveguen a la URL del archivo real al bloquear el acceso a la carpeta /wp-content/uploads/dlm_uploads/ .

Bonificación: si hace esto para un sitio donde necesita que los usuarios puedan iniciar sesión como 'Miembros' solamente (pero no tienen permisos de WordPress como la edición de páginas o ser un administrador), instale el complemento 'Miembros' enlace , crea un nuevo rol de usuario llamado 'Miembro' y dale la capacidad única de 'leer', crea un nuevo Usuario en WordPress , y asegúrese de darles un rol de 'Miembro'.

Si desea proteger el contenido de las páginas, el complemento 'Miembros' ofrece algunas opciones, o existen otros complementos. Si desea asignar un tema a la página de inicio de sesión para que los miembros se vean mejor que el formulario de inicio de sesión predeterminado de WordPress, use algo como 'Tema Mi inicio de sesión': enlace

    
respondido por el Matty J 13.04.2017 - 11:09

Lea otras preguntas en las etiquetas