views:

81

answers:

5

I'm looking for a way to prevent unauthorised users from viewing pages without, lets say, wrapping everything in an if authed { show page } else { show error}

My website is currently setup like:

index.php

require_once __WEBROOT__ . '/templates/default/header.tmpl';
require_once content('p');
require_once __WEBROOT__ . '/templates/default/footer.tmpl';

content()

function content($GETvar)
{
   $content  = '';
   $root     = __WEBROOT__;
   $location = 'content';
   $files    = scanDirRecursive($root . '/content/');

   if (isset ($_GET[$GETvar]))
   {
      $path = str_replace('\\', '/', $_GET[$GETvar]->toHTML());

      if (in_array("$root/$location/$path", $files))
      {
         $content = "$root/$location/$path";
      }
      else
      {
         $content = $root . '/templates/default/errors/404.php';
      }
   }
   else
   {
      $content = __WEBROOT__ . '/content/home.php';
   }

   return $content;
}

This works nicely. When I was playing around with auth options, I chucked in a 'return' at the top of 'content' page. Which ended up preventing the content page from loading but keeping the template in tact (unlike a die()).

So I was wondering, is this safe? Or is there an error occurring that I'm not seeing...

+1  A: 

Require a login page which sets a session variable with, say, the userid. Then on every page, call a function to check for authorization. It could probably be put in the header if it considers both the page and the user.

If no user is logged in, or they aren't allowed for the page, redirect to the login page—it would be nice to add a message saying they can't use the page they requested without logging in.

Logging out should clear the session variables. Also, if there is to be a session timeout, record the timestamp in a session variable at times which reset the timeout.

wallyk
+1  A: 

Why to reinvent the wheel? Every php framework have it's acl module, where you can set security policy with minimal amount of coding. Take a look at cakephp or in google acl framework...

Timon
Not everyone uses a framework.
Xorlev
sure is nice to use a framework. I started using cakephp and the amount of code i was writing easily got cut in half
WalterJ89
A: 

don't do a if logged in do this {} else {complain,} just redirect them to the login page if they aren't identified then die();

kyle
+2  A: 

Use the front controller pattern. Instead of having all your pages as individual PHP files, have a single "point of entry".

Basically, have your index.php file work like index.php?p=foo where foo defines what page to show. This way, all your requests will go through index.php, and you can include all your access checking in a single place. Remember to be careful to not allow including arbitrary files though - a common beginner mistake with this approach.

However, as pointed out, you may wish to research how frameworks like Cake or Zend perform this job.

Jani Hartikainen
A: 

I've found it convenient to simply throw an Exception for such things. There are several strategies, but one might involve a scenario like:

function show_content()
{
  if( ! $user_is_allowed_to_see_this_content ) {
    throw new Exception('This user may not see this content', 403);
  }

  // Continue on with the content code
}

By default, this will simply error out, but you can use the set_exception_handler() function to define what specifically happens when the exception is thrown. This lets you define the "what to do when stuff goes wrong" logic in a separate place from your content-handling code, which I find makes things tidier.

For example:

function custom_exception_handler( Exception $exception ) 
{
  // Log the Exception
  error_log( $exception->getMessage(), 0 );

  // Return the generic "we screwed up" http status code
  header( "HTTP/1.0 500 Internal Server Error" );

  // return some error content
  die("We're sorry.  Something broke.  Please try again.");
}

// Now tell php to use this function to handle un-caught exceptions
set_exception_handler('custom_exception_handler');

It's worth noting that this is a good general-purpose way to handle all logical failure events, and not just authentication failures. File-not-found exceptions, validation exceptions, database query exceptions, demand-throttling exceptions; these can all be handled in the same way and in the same place.

Jonathan Hanson