简体   繁体   中英

PHP looking for a neat way to prevent unauthorised users from viewing pages

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:

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

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...

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.

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.

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...

如果登录,请不要执行此操作{} else {complain,}只是将它们重定向到登录页面,如果它们未被识别,则die();

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM