There are times when you want all or part of your Magento online store to only be visible to customers who are logged in to the website. Once such example is a “wholesale” website where only approved wholesale users should be able to view products and checkout. This functionality is not built in to Magento, but it’s a just a few simple little code hacks away.
NOTE: On 8.25.09 I updated this post since I have improved the technique.
Create a redirect .phtml template
First, create a small file in the /template/page/html directory of your active theme. Call it something like auth-redirect.phtml. The contents are just:
==<?php== Mage::getSingleton('customer/session')->setBeforeAuthUrl($this->getRequest()->getRequestUri()); //save requested URL for later redirection
if(!Mage::getSingleton('customer/session')->isLoggedIn()) { // if not logged in
header("Status: 301");
header('Location: '.Mage::helper('core/url')->getHomeUrl(customer/account/login)) ; // send to the login page
exit;
} ?>
Note: Apparently, for Magento 1.4, you should use this code (but I have not tested it):
==<?php== Mage::getSingleton('customer/session')->setBeforeAuthUrl($this->getRequest()->getRequestUri()); //save requested URL for later redirection
if(!Mage::getSingleton('customer/session')->isLoggedIn()) { // if not logged in
header("Status: 301");
header('Location: '.$this->getUrl('customer/account/login')) ; // send to the login page
exit;
} ?>
Right now the 301 redirects to the login page, but it could be the homepage or somewhere else as well. The first line ensures that after logging in, the user is redirected to the page they first tried to access. Removing that line means the user gets redirected to their Account page after logging in, I believe.
Edit page.xml
Now we want to make the redirect code in auth-redirect.phtml available to all of the page templates on our website. In layout/page.xml in your active theme, add the following line of code:
<block type="page/html" name="auth-redirect" as="auth-redirect" template="page/html/auth-redirect.phtml"/>
Insert this as the first item under the “root” Block (i.e. <block type=“page/html” name=“root” output="toHtml">)
Edit page layout templates
Now that the redirect code in auth-redirect.phtml is available, we need to include it in all of the page templates. The “page templates” I’m referring to, in the page directory of your theme, are:
- 1column.phtml
- 2columns-left.phtml
- 2columns-right.phtml
- 3columns.phtml
- etc etc
Insert the following line into all of them, at the top of the file just after the “<?php” tag.
echo $this->getChildHtml('auth-redirect')
This ensures that the redirect is included before any of the page HTML renders.
Add exceptions (or: public pages)
Finally, we need to add “exceptions” – public pages like the “login” page which don’t need to be protected. On a site that is only accessible to logged in users, the login page needs to be public!! To enable the login page, go to layout/customer.xml and add the following to the <customer_account_login>
block:
<remove name="auth-redirect" />
If you want users to be able to create an account, another good one to make public might be <customer_account_create>
in layout/customer.xml.
If you want to make the home (front) page public, add the “remove” code to the <cms_index_index>
block in layout/page.xml.
You can also add this code to the custom “Layout Update XML” on any category, product or CMS page to make them public.
And your done!
That’s it. Now, if you want to protect just certain parts of a Magento store, or control access based on user Roles, you will have to get a little fancier. I’m not covering that here, but…
One way to do that might be to NOT add the auth-redirect block to the master page.xml (and then do exceptions), but instead to only place it on certain pages like the Cart and Checkout (so the catalog is visible, but you can’t purchase without logging in).
Alternatively, you can control access by placing the conditional with ==<?php== Mage::getSingleton('customer/session')->isLoggedIn() ?>
right in specific PHP of pages you want to protect. Some folks check for specific pages by URL using $_SERVER['REQUEST_URI']
with this technique. There’s more on this in the Magento forums here.