Domanda

I'm trying to implement an ACL in my database. I have a database which looks like:

SYS_USERS { id, name, .. }
AUTH { au_id, au_name, .. }
USER_GROUPS { sys_users_id, auth_id } // bridge table

And say AUTH data looks like:

au_id    au_name    ...
    1      admin    ...
    2      staff    ...
  ...        ...    ...

My question is, how can I structure my query from php such that upon login, depending on your authentication level, you are presented different pages?

At the moment I have this, which seems a little off:

<?php
// code which verifies session variables etc here

$mysql_hostname = 'localhost';
$mysql_username = '...';
$mysql_password = '...';
$mysql_dbname = '...';

try {
    /* Set up new DB object */
    $db = new PDO("mysql:host=$mysql_hostname;dbname=$mysql_dbname", $mysql_username, $mysql_password);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    /* authenticate user access level */
    // username = 'blah' for question clarity
    $query = $db->prepare('SELECT au_name FROM auth WHERE au_id = (SELECT auth_id FROM user_groups WHERE sys_users_id = (SELECT id FROM sys_users WHERE username="blah"))');

    // do something with results..

} catch(Exception $exception) {
    $message = 'We are unable to process your request. Please try again later';
}                  

?>

So I guess my questions are:

  1. Is the SELECT query adequate? Or should I use an INNER JOIN to achieve the same results? (Does it matter?)
  2. Upon success of the query, how do I show the page depending on the level? For example, if it returned admin do I write a function such that


if ($result == 'admin') {
      // show admin.php
    } elseif ($result == 'staff') {
      // show staff.php
    } else { ... }

But this seems rather 'hard coded', i.e. if we were to extend the system for more AUTH roles, we would need to then add in more IF/ELSEIF statements to the above.

Anyone able to lead me in the right direction?

Thanks.

EDIT
So I was thinking of a new way to do this. I could add two more database tables:

PAGES { id, page_name .. }
AUTH_PAGES { au_id, pages_id, .. } // bridge between auth and pages

Which then in pages I could store page_name which would hold the authentication level required to view that page?

For example:
a page called admin_page.php could only be accessed by administrators. Therefore this row in pages looks like:

id           page_name        
 1      admin_page.php
 2    members_page.php

and auth_pages:

au_id    pages_id
    1           1
    1           2

Which is to say the auth row admin (au_name) has access to admin_page.php and members_page.php. Then all I would need to do in my PHP would be to cross reference the page name with the id from pages table with auth_pages table using echo basename($_SERVER['PHP_SELF']);.

Does that make any practical sense?

È stato utile?

Soluzione

Since you mentioned its going to be simple so this is what I can suggest you.

At the time of login get the user id and then run a query with the id user as

select 
a.au_name,a.au_id
from USER_GROUPS ag
inner join SYS_USERS su on su.id = ag.sys_users_id
inner join AUTH a on a.au_id = ag.auth_id
where ag.sys_users_id = {id of the user retrieved after the login validation}

Now Execute the above query and get the au_name and store it in a session variable as

$_SESSION['au_name'] = {auth name from the above query} ;

Create a function as below and execute it after the login.

get_page_access($au_id){
  run  a query to get all the pages for the auth id you got from previous query
  store them in an array and finally to a session variable as
  $_SESSION['page_access'] = $array ; 
  $array will hold all the pages you retrive
}

Now do the redirect based on the $_SESSION['au_name'] firstime after the login.

Now what if user hotlink an URL i.e. a non-admin user try to access a page. So for that create a file called check_access.php and add include it to all the pages other than the login page.

In this page you get the URL using PHP and get the filename from the URL, then check if that filename exists on the array $_SESSION['page_access'] and if yes user is allowed to view the page else show message.

Make sure you do session_start() before the include .

This will be fairly simple in nature

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top