Comment protéger les téléchargements, si l'utilisateur n'est pas connecté?

70

J'utilise wordpress pour un site privé où les utilisateurs téléchargent des fichiers. J'utilise le "WordPress privé" pour empêcher l'accès au site si l'utilisateur n'est pas connecté.

Je voudrais faire la même chose pour les fichiers téléchargés dans le dossier des téléchargements.

Ainsi, si un utilisateur n'est pas connecté, il ne pourra pas accéder à: enlace s’ils essaient d’y accéder mais qu’ils ne sont pas connectés, ils doivent être redirigés vers la page de connexion, par exemple.

J'ai trouvé un plugin appelé fichiers privés, mais la dernière fois mis à jour remonte à 2009, il ne semble pas fonctionner sur mon wordpress.

Quelqu'un connaît une méthode? La méthode Hotlinking suffira-t-elle à protéger cela?

J'ai aussi trouvé cette méthode:

# 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

Mais alors tout utilisateur qui réplique le cookie peut-il passer ce droit? Cordialement

    
posée chifliiiii 22.12.2011 - 17:46

3 réponses

78

Vérifier uniquement si le cookie existe ne constitue pas une protection stricte.

Pour obtenir une protection renforcée, vous pouvez transmettre ou "utiliser un proxy" à toutes les demandes du dossier téléchargé (par exemple, uploads dans l'exemple suivant) via un script php:

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

Toutes les demandes de fichiers téléchargés (y compris les images dans les publications) iront à dl-file.php , ce qui permettra ensuite de vérifier si l'utilisateur est connecté ou non.

Si l'utilisateur n'est pas connecté, le formulaire de connexion de votre site sera affiché. Une fois l’utilisateur connecté, il sera redirigé vers le fichier et pourra le télécharger maintenant.

Exemple de dl-file.php .

Quelque chose de similaire peut être trouvé dans \wp-includes\ms-files.php dans votre installation de wordpress, mais celui-ci est destiné aux multisites et sans contrôle de connexion ni redirections.

En fonction de votre trafic, il peut être judicieux de mieux l'intégrer à votre serveur, par exemple. X-Accel-Redirect ou X-Sendfile en-têtes.

    
réponse donnée hakre 02.01.2012 - 22:50
14

Vous pouvez également écrire un plugin en utilisant le crochet init et la valeur get $_GET[ 'file' ]; . Si l’utilisateur a cette valeur d’obtention, sautez dans une fonction pour vérifier les droits d’accès aux fichiers: par exemple, avec une case à cocher dans une boîte méta.

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

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

Vous pouvez également ajouter une URL personnalisée pour les fichiers via le 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;
}
    
réponse donnée bueltge 03.01.2012 - 11:20
1

Si vous souhaitez une approche par plug-in pour résoudre ce problème, voici une solution relativement bonne que j'ai (enfin) trouvée:

  1. Installez le plugin "Download Monitor", disponible à l'adresse suivante: enlace
  2. Dans le tableau de bord WordPress, allez au nouvel élément de menu "Téléchargements" et ajoutez un nouveau "Télécharger", comme décrit dans la documentation du plugin. site Web ici: enlace . Prenez note du shortcode "Télécharger" fourni (par exemple, enregistrer dans Bloc-notes). Notez que le fichier est enregistré dans /wp-content/uploads/dlm_uploads/
  3. Dans la boîte à outils "Options de téléchargement", spécifiez "Membres uniquement" (comme documenté ici enlace . ) et cliquez sur 'Publier'.
  4. Sur la page à télécharger uniquement par les membres, ajoutez le shortcode que vous avez noté à l'étape 2 et "Publiez / mettez à jour" la page, comme indiqué ici: enlace . Vous pouvez modifier le modèle de lien de téléchargement comme décrit ici enlace , ou créer le vôtre (par exemple, pour le supprimer). le "compte" de téléchargement)
  5. Accédez à votre page, vous devriez voir un lien de téléchargement (mais qui ne révèle pas l’URL du fichier téléchargé). Si vous accédez à la même page dans une nouvelle fenêtre du navigateur (ou une fenêtre Incognito), vous constaterez que le téléchargement ne fonctionne plus.

Cela signifie que les personnes non connectées ne peuvent ni télécharger le fichier, ni voir l'URL réelle du fichier. Si, dans le cas où une personne non autorisée détermine l'URL du fichier, le plug-in empêche également les utilisateurs d'accéder à l'URL du fichier réel en bloquant l'accès au dossier /wp-content/uploads/dlm_uploads/ .

Bonus: si vous le faites pour un site où vous avez besoin que les utilisateurs puissent se connecter en tant que "Membres" (sans disposer d'autorisations WordPress telles que l'édition de page ou d'être un administrateur), installez le plug-in "Membres" enlace , créez un nouveau rôle d'utilisateur appelé "Membre" et donnez-lui la capacité unique de "lire", créez un nouvel utilisateur dans WordPress et assurez-vous de leur attribuer un rôle de «membre».

Si vous souhaitez protéger le contenu des pages, le plug-in "Membres" fournit des options ou d'autres plug-ins. Si vous souhaitez créer un thème pour la page de connexion afin que les membres aient une meilleure apparence que le formulaire de connexion par défaut WordPress, utilisez quelque chose du genre "Thème Mon identifiant": enlace

    
réponse donnée Matty J 13.04.2017 - 11:09

Lire d'autres questions sur les étiquettes