Make images private in WordPress

I’m making a site, that I would like to make private. The most important part, is that the images on the domain can’t be seen, without the user logging in first.
So I would like all traffic to be redirected to www.DOMAINNAME.com/wp-admin (also for images), if the user isn’t logged in.

Here’s what I’ve tried:

Read More

1) Plugins. I’ve tried both WordPress Force Login , the plugin wp-require-login and a Coming soon page and Maintenance mode.

2) Adding a function from this answer. Which is this:

function is_login_page() {
    return in_array( $GLOBALS['pagenow'], array( 'wp-login.php', 'wp-register.php' ) );
}

function wpse_make_blog_private() {
    if ( ! is_user_logged_in() && ! is_admin() && ! is_login_page() ) { 
    global $wp_query;
    $wp_query->set_404();
    }
}
add_action( 'wp', 'wpse_make_blog_private' );

Non of these things redirects the traffic, if I go to the direct URL for the image (such as http://www.DOMAINNAME.com/uploads/2015/10/foobar.jpg ).

Can that be done?

—————– EDIT 1 ————–

Mevius pointed out, that WordPress might not be loaded, if you type in the direct URL to an image, so he suggests, that it should be done on apache-level.

————- END OF EDIT 1 ———–

Related posts

4 comments

  1. You can make this as complicated or as simple as you want. The simplest is to check the referrer as suggested by Hemnath Mouli but that can spoofed easily.

    However, if you want to go really deep… 😉

    Use .htacess file with a RewriteRule to rewrite all images into a PHP script that bootstraps WordPress and checks the user’s authentication status. Also you should add an .htaccess file to your images folder to deny direct access to the folder to exclude edge cases.

    WARNING: THIS CODE IS JUST PROOF OF CONCEPT TO GET YOU STARTED!!

    .htaccess

    RewriteRule ^(.*.(jpg|gif|png))$ isAuthenticated.php?path=$1

    isAuthenticated.php

    require_once("wp-blog-header.php");
    
    $allowedExtensions = array("jpg", "gif", "png");
    
    $path = $_SERVER["DOCUMENT_ROOT"].DIRECTORY_SEPARATOR.$_REQUEST["path"];
    $pathInfo = pathinfo($path);
    
    // Check if the WordPress user is logged in and if the file extension is allowed
    // @see https://codex.wordpress.org/Function_Reference/is_user_logged_in
    if (!is_user_logged_in() || !in_array($pathInfo["extension"], $allowedExtensions)) {
        header("HTTP/1.1 403 Forbidden");
        exit;
    }
    
    if(!file_exists($path)) {
        header("HTTP/1.1 404 Not Found");
        exit;
    }
    
    // Display the file and set the correct mimetype
    $resource = finfo_open(FILEINFO_MIME_TYPE);
    $mimetype = finfo_file($resource, $path);
    finfo_close($resource);
    
    header("Content-Type: ".$mimetype);
    readfile($path);
    
  2. Use .htaccess

    RewriteEngine on 
    RewriteCond %{HTTP_REFERER} !^http://(www.)?localhost [NC] 
    RewriteCond %{HTTP_REFERER} !^http://(www.)?localhost.*$ [NC] 
    RewriteRule .(gif|jpg)$ - [F]
    

    Returns 403 if you access image directly, but allows them to be displayed on site.

  3. Use .htaccess

    RewriteEngine on 
    RewriteCond %{HTTP_REFERER} !^http://(www.)?localhost [NC] 
    RewriteCond %{HTTP_REFERER} !^http://(www.)?localhost.*$ [NC] 
    RewriteRule .(gif|jpg)$ - [F]
    

Comments are closed.