Private pdf files

I would like to give access some private pdf files to only logged in users.

I have this in my htaccess:

RewriteCond %{REQUEST_FILENAME} ^.*(pdf)$
RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in.*$ [NC]
RewriteRule . - [R=403,L]

But I want to restrict access only documents .pdf with name starts with "private_".

Example: private_document1.pdf and private_document2.pdf only have to be accessible by logged in users.

Please, any ideas?

Topic private documentation pdf Wordpress

Category Web


Your approach does not provide security. I could hand-craft a cookie named "wordpress_logged_in" (containing any arbitrary value) and have access to your PDF files.

You may want to rethink your solution to put a PHP script in between the files and the users.

e.g.

  1. User Clicks download button
  2. PHP Script handles fetching document
  3. If authenticated user, PHP script sends through PDF file.
  4. If not authenticated, send error message.

Take a look at this answer for more detail on implementation: https://stackoverflow.com/questions/10834196/secure-files-for-download

If this is an approach you would like to explore, I will update my answer with how to connect this approach to WordPress.


Edit: I'm going to provide a "hacky" solution for proof-of-concept. In practice, I would likely implement the approach using WP AJAX actions.

<?php

/*
 * Assume WordPress lives in /var/www/mysite/
 * This script's path is /var/www/mysite/downloader.php
 *
 * To download a file, link the user to:
 *   <a href="/downloader.php">Download file</a>
 *
 * You can mask this downloader using htaccess rewrites
 */

// Load wordpress
require_once('/path/to/wordpress/wp-load.php');

if (!is_user_logged_in()) die('no access');

// specify a file path
$file = '/path/to/file/outside/www/secret.pdf';

// or load the file from some other location (e.g. WP Media)


header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;

// Don't use closing PHP brackets.

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.