For example my main domain www.example.com
which is a file sharing website where we keep files in sub domain like server1.example.com
and server2.example.com
to share with visitor. My question is how to protect a file on sub-domain (sub-domain might point to different server or host) direct from download without authentication in wordpress/mainsite.
My current code credit goes to http://wordpress.stackexchange.com/a/37743/12438
.htaccess file
RewriteCond %{REQUEST_FILENAME} -s
RewriteRule ^wp-content/uploads/(.*)$ dl-file.php?file=$1 [QSA,L]
SO my entire .htaccess code looks like
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
# BEGIN THIS DL-FILE.PHP ADDITION
RewriteCond %{REQUEST_URI} ^.*wp-content/uploads/.*
RewriteRule ^wp-content/uploads/(.*)$ dl-file.php?file=$1 [QSA,L]
# END THIS DL-FILE.PHP ADDITION
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Options -Indexes
but it can Protect only a file inside wp-content/uploads/*
here is dl-file.php
<?php
ob_start();
require_once('wp-load.php');
require_once ABSPATH . WPINC . '/formatting.php';
require_once ABSPATH . WPINC . '/capabilities.php';
require_once ABSPATH . WPINC . '/user.php';
require_once ABSPATH . WPINC . '/meta.php';
require_once ABSPATH . WPINC . '/post.php';
require_once ABSPATH . WPINC . '/pluggable.php';
wp_cookie_constants();
$discard = ob_get_clean();
is_user_logged_in() || auth_redirect();
list($basedir) = array_values(array_intersect_key(wp_upload_dir(), array('basedir' => 1)))+array(NULL);
$file = rtrim($basedir, '/') . '/' . (isset($_GET['file']) ? $_GET['file'] : '');
$file = realpath($file);
if ($file === FALSE || !$basedir || !is_file($file)) {
status_header(404);
die('404 — File not found.');
}
if (strpos($file, $basedir) !== 0) {
status_header(403);
die('403 — Access denied.');
}
$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 );
Step 1:
Add the following to the '.htaccess' of all sub domains.
In the above code, we are redirecting all the files to the main domain except if a post parameter set. For example,
http://server1.example.com/file.pdf
will be redirected tohttp://www.example.com/?dwnld_file=server1/file.pdf
. Hereserver1
is your sub domain name in order to identify if multiple sub domains.In the rewrite condition -
RewriteCond %{QUERY_STRING} !key=(FgTyUeL)
,key
and its valueFgTyUeL
should be confidential and feel free to change to more complex strings. We will use this to access the file in WordPress.Step 2:
Add these to your theme's 'functions.php' of main domain.
The above functions are self-explanatory - we are checking WordPress authentication and if logged-in user, we will append the secure key and download the file using cURL. Please note that the secure key should be same as the one in the '.htaccess' file of your sub domain(s).
Put protected files in a private folder outside of the publicly accessible area of your web site. Then, make a download page that takes a file name in the url or whatever. Then on that page, do the auth check: