A simple way to limit file downloads to only logged in users in WordPress

05 Sep

So, you’ve used WordPress to build your client’s site and to provide downloads for the site’s users. You’re hiding the links to download content based on the user’s logged in status. Great. But what happens when the logged in user copies the download URL and sends it to his friend? Well, unless you’re filtering the download links and checking them with WordPress first his friend gets to download the file.

I’m not a big fan of checking every file download with WordPress as it can take a lot of overhead if you’re running a busy site. So here is a pretty straight forward way to limit downloads from a WordPress site with a minimal amount of code. In this example I’ll illustrate how to prevent non-logged in users from downloading audio files in mp3 and m4aformat.


Basic Blocking

First, lets use some ModRewrite rules to get Apache to show users a 403 forbidden page when trying to access the files. This isn’t pretty, it simply gets Apache to dump the user in to a default 403 page and the user is told that their access is forbidden. The .htaccess changes:


  1.  # These next two lines will already exist in your .htaccess file
  2.  RewriteEngine On
  3.  RewriteBase /
  4.  # Add these lines right after the preceding two
  5.  RewriteCond %{REQUEST_FILENAME} ^.*(mp3|m4a)$
  6.  RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in.*$ [NC]
  7.  RewriteRule . – [R=403,L]


On the first line of this code you’ll see (mp3|m4a). This is the part that looks at the ending of the file name and determines which files it will act upon. replace the items inside the parentheses with the file types that you want to protect, each one separated by the pipe character. So, for example, if you wanted to protect PDF and RTF files you’d change it to:RewriteCond %{REQUEST_FILENAME} ^.*(pdf|doc)$

That is really all we need but its not very nice to dump the user like that and not inform them of why they were forbidden. They may assume that the site is broken. So lets do this the right way and get the users redirected to a page that will inform them of why they were denied access to the content.

Redirecting the Access Denied

For this we’ll need a page template. You can create anything you’d like, but the basics of it are:


  1.  <?php
  2.  /**
  3.   * Template Name: 403
  4.   *
  5.   * The template for displaying 403 pages (Forbidden/Not Allowed).
  6.   */
  7.   get_header(); ?>
  8.   <div id=”container”>
  9.   <div id=”content” role=”main”>
  10.   <div id=”post-0″>
  11.   <h1><?php _e( “Action Not Allowed”, “twentyten” ); ?></h1>
  12.   <div>
  13.   <p><?php _e(“Apologies, but you are not allowed to download files while not logged in.”, “twentyten”; ); ?></p>
  14.   </div><!– .entry-content –>
  15.   </div><!– #post-0 –>
  16.   </div><!– #content –>
  17.   </div><!– #container –>
  18.  <?php get_footer(); ?>


Your template will obviously look a bit different. I did this one as an extension to the new Twenty Ten theme in WordPress 3.0 and based it off of the provided 404 template.

Save the file to your theme’s directory. It doesn’t matter what you name it. WordPress will actually pick up on the Template Name: 403 portion as the template ID.

Next we need to create a page in the WordPress admin for our notification page. Create a new page, name it whatever you want. For my purposes I titled the page “Not Allowed” so my slug ended up as “not-allowed”. You can edit these to be any values you want if the page title created a slug that you don’t like. You’ll need that slug here in the next step. Next select the 403 page template from page templates select input in the Attributes meta box (typically on the right side of the page, underneath the Publish button. Publish the page.

Now let’s alter that .htacess directive to redirect to this page instead of showing that unfriendly Apache notice. The modified directives are:


  1.  RewriteCond %{REQUEST_FILENAME} ^.*(mp3|m4a)$
  2.  RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in.*$ [NC]
  3.  RewriteRule . /not-allowed [R,L]


The relevant change happened on the third line where the dash was replaced by the relative url to my 403 page. In my case that is /not-allowed. Yours will differ depending upon how named your page. Don’t forget the leading slash when adding your slug so that it’s a valid relative path. (This can be an absolute path as well, ie: one that contains the full but there’s no need to do that here unless you’ve got valid reason to do so, like if you want to redirect the user to a different domain).

Now, whenever someone who is not logged in tries to download a file type that you’ve specified they’ll be redirected to your 403 page. What you tell them there is up to you.


…now, if you’re theme lists out pages anywhere, you’ve got this 403 page sticking its nose in where it doesn’t belong. Not very pretty, now, is it? This is pretty easily remedied. Head on in to the WP Admin and to the page edit screen for the 403 page. Take note of its page ID in the url. It will be the number after the word “post=” in the url. For example, if your URL looks like http://wp30.local/wp-admin/post.php?post=8&action=edit the post id is 8.

We now need to make an addition to your theme’s functions.php file. This file is located in your theme directory. Open this file and add in the following code:


  1.  <?php
  2.  // Do error page excludes
  3.  function exclude_error_pages($excludes) {
  4.   array_push($excludes, 8);
  5.   return $excludes;
  6.  }
  7.  // we don’t want any funny stuff in the admin, only add to front end
  8.  if (!is_admin()) {
  9.   add_filter(‘wp_list_pages_excludes’, ‘exclude_error_pages’);
  10.  }
  11.  ?>


On the line that says array_push($excludes, 8); replace the 8 with the id of the page you just created. This will keep the function wp_list_pages() from outputting the 403 page in any of its lists.

Note: if you’ve got other places in your theme that are pulling page lists through different means you’ll want to modify or filter those results as well. Depending upon the methods used to make the lists you can probably exclude the page as a parameter of the call for pages instead of using a filter. Your mileage will vary, but it is certainly doable.

Ta da!

And there you have it. Simple and straight forward. No real frills, though. As it sits now the user is redirected to a page that just tells then simply that they need to be a logged in user. That’s not very informative all by itself. There are a hundred ways to modify this to make it more convenient on the user.

Hopefully this gives you some ideas on what can be done to help legitimate users get to your content while keeping the rif-raff from poaching it.

1 Comment

Posted by on September 5, 2013 in Wordpress


One response to “A simple way to limit file downloads to only logged in users in WordPress

  1. ugg slippers for men

    September 13, 2013 at 5:45 pm

    The bottom line is that the bottom of the mouse stays clean and that is the most important thing.Therefore, it is not unusual to see her dressed up in funky outfits.Hello Kitty Keychain Is your lady constantly losing her house keys and you commit hours seeking for them.Some paradegoers had camped out to get a good spot, staying snug in sleeping bags.Toys R US in Albany Action Figures, Air Hockey, Arts Crafts, Audio Tapes, Automobiles Trains, Baby Furniture, Balls, Banners Flags, Beach Toys, Bicycles Tricycles, Board Games, Boats Planes, Bocce, Books Magazines, Boy Dolls, Building Sets Blocks, Card Games, Carriages / Buggies / Strollers, Celebrity Dolls, Classic Traditional Toys, Collectible Dolls, Computer Games, Console Games, Costumes, Croquet, Darts, Doll Houses, DVDs, Electronic Games, Electronic Toys, Ethnic Dolls, Foosball, Game Boy Advance Games, Game Tables, GameCube Games, Girl Dolls, Hair / Wigs, Inflatables, Kids’ Audio Video Players, Kids’ Cameras, Kids’ Sporting Goods, Kites, Memorabilia, Mini Golf, Miniature Dolls, Miniature Games, Movies, Musical Instruments, Nintendo DS Games, Novelties, Party Games, Party Goods, PC Games, Play Structures, Playing Cards, Playstation 2 Games, Playstation 3 Games, Plug ‘n Play Handheld Games, Powered RideOns, PSP Games, Radio Control Remote Control, Remote Control Cars, RideOn Toys, Riding Toys, Robots, Rollerblades Roller Skates, School Supplies, Skateboards, Slides, Socks, Software, Stuffed Animals, Swing Sets, Trading Cards, Traditional Classic Games, Trampolines, Travel Games, Video Game Systems, Video Tapes, Wagons, Water Toys, Wii Games, Xbox 360 Games, Xbox Games, YoYos Activision, Adidas, Alex, Amazing Live SeaMonkeys, American Idol, American Retro, Baby Born, Baby Einstein, Backyardigans, Badger Basket, Balitono, Bandai, Barbie, Batman, Bell Sports, Ben 10, Bergamot, Blue Box Inc.In college, Walch was accustomed to jogging off the field to indicate hustle.And most importantly, people are no longer their jewelry for significant special occasions.In applying at this time I find the product gets all the way down the shaft to the skin.There are cheaper ros out there, and if we’re going to spend $30 on a bottle, it probably won’t be this one.Leone reminded her daughter, only half kidding, as Maggie snuggled her chin onto her mom shoulder and the two stared at the tree, waiting for it to light up.


Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: