Requiring Registration to Download Files in Drupal
We often have clients request that people register on the site before they are able to download files. This is often in order to use the files as lead nurturing. Luckily Drupal has all the pieces to make this happen even though they are a bit spread out. This is how we do it.
Modules you will need:
r4032login
luxe (or logintoboggan)
private_files_download_permission
Step 1 - Set up the Private Filesystem
Go to Configuration->Media->File system (admin/config/media/file-system)
In the private file system path, set up the private file system. A safe default is sites/default/files/private
Step 2 - Setup Private files permissions
Install and enable the module private_files_download_permission (http://drupal.org/project/private_files_download_permission)
Go to Configuration->Media->Private Files Download Permission
Click "Add directory" to add a directory
In the Path field enter "/" (You can also optionally select a subdirectory if you only want to protect some files)
Under Enabled Roles, select "authenticated user"
Save the directory to the control list
This sets up access permissions to the files so that only authenticated users can access the files. Everyone else will get a 403 Permission Denied error (See Step 4).
Step 3 - Create a content type with a file field
Create a content type or other entity type.
Add a file field to the content type.
Under the field settings, select "Private files" (On the next page ensure that you select Private files for upload location again)
If you entered a subdirectory in Step 2, enter the same directory in the field settings.
Save the field.
The site is now set up to save files in this field to private files.
Step 4 - Set up 403 Permission Denied Redirect
We don't actually want people to get a permission denied message when they try and access the files, we really want them to be presented with a page to either log in or register to access the files. To do this use the r4032login module. This is a simple module that detects a 403 message and sends visitors to /user/login if they haven't logged in yet.
Install and enable the r4032login module (http://drupal.org/project/r4032login)
Go to Configuration->System->Site Information
Verify that under Error Pages the 403 (access denied) is now set to r4032login
Now when users attempt to access a file and should get a 403 error, the are instead sent to the user/login page.
Step 5 - Enable registration on the login page
We need to add a registration form on the login page. This is a better user experience and if we leave the drupal defaults as is, if a user tries to register it will lose the redirect information to send them back to the file they were trying to download. By combining the login and registration form on the same page no matter if they register or login, they will be sent back to the file.
Install and enable the luxe module (http://drupal.org/project/luxe)
Go to Configuration->User Interface->Luxe
Check the box that says "Show full registration form on login page"
Change any other settings you want to change and save the configuration
Go to Configuration->People->Account Settings
Under Registration and Cancellation, Who can register accounts select "Visitors"
Uncheck "Require e-mail verification when a visitor creates an account"
The reason we changed these settings is that if we verify the email address the user is sent a link without the destination set so we can no longer send them back to the file they were requesting. This is poor usability from the end users perspective as they just registered and expect to be sent back to the resource they were requesting and instead have to find the file again. See Bonus at the bottom for more information.
WARNING!!!
By doing the above steps we have essentially enabled ANYONE to create an account without verifying their email address or verifying that they are a human. It is HIGHLY recommended that you install mollom or some other form of captcha or you will very shortly have many, many spammers signed up for your website.
Logintoboggan (http://drupal.org/project/logintoboggan) can be used to place a registration form on the login page but we didn't like the functionality as much so we recommend luxe. Your methods may vary.
Step 6 - Redirecting to the node page after registration
At this point we have a site that will require authentication before downloading private files. The problem now is that when a user logs in or registers, they immediately download the file and are left on the login/register page. We don't really want this as once the file is downloaded they get very confused. Ideally we would redirect them to the page they were originally on and start the file download. I haven't actually found a way to do BOTH of these things so the workaround we use right now is to send them back to the page that contains the file and display a message telling them to click on the file again. This is how we do it.
In a custom module put the following:
Bonus - Adding email verification to the registration process
In Step 5 above we opened up registration to anyone without verifying their email address. This is not terribly secure and many people will enter bogus email addresses. It would be much better to require them to click on a verification link in their email before you log them in and allow them to download a file. Unfortunately this adds a lot of complexity to the process. We did implement it for a client a couple years ago in Drupal 6 and the same process would work in Drupal 7 but we don't have any code for it yet.
Here is how the custom module worked that we developed for them. First, it hooked into the user_register_submit form and looked for a ?destination query string. If it existed it would write a row in a database table along with the email address of the person registering. Then it hooked into the user login with hook_user_login and when a user logged in it would check the table for a redirect for that user's email address and send them to the recorded destination. It would then mark the redirect as used so the next time they logged in it wouldn't send them to the same page again.
That's it! It would be great if all of this (especially Steps 2, 6, and Bonus) were combined in one module and easier to set up. If someone wants to, let me know or I may if I find the time and one of our clients requires it.
Any ideas on improving the process?
Photo Credit: http://www.photoree.com/photos/permalink/1086677-27718575@N07