Private pdf files

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="https://wordpress.stackexchange.com/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.