我试图在我的数据库中实现ACL。我有一个看起来像这样的数据库:
SYS_USERS { id, name, .. }
AUTH { au_id, au_name, .. }
USER_GROUPS { sys_users_id, auth_id } // bridge table
并说AUTH
数据如下:
au_id au_name ...
1 admin ...
2 staff ...
... ... ...
我的问题是,如何从php
构建我的查询,以便在登录时,根据您的身份验证级别,您会看到不同的页面?
目前我有这个,这似乎有点偏离:
<?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';
}
&GT;
所以我想我的问题是:
SELECT
查询是否足够?或者我应该使用INNER JOIN
来获得相同的结果? (这有关系吗?)admin
,我是否写了一个函数
if ($result == 'admin') {
// show admin.php
} elseif ($result == 'staff') {
// show staff.php
} else { ... }
但这似乎很难编码&#39;,即如果我们要扩展系统以获得更多AUTH
个角色,我们需要添加更多IF/ELSEIF
语句到上方。
任何人都能引导我朝着正确的方向前进吗?
感谢。
修改
所以我想到了一种新方法。我可以再添加两个数据库表:
PAGES { id, page_name .. }
AUTH_PAGES { au_id, pages_id, .. } // bridge between auth and pages
然后在pages
我可以存储page_name
哪个会保存查看该页面所需的身份验证级别?
例如:
只有管理员才能访问名为admin_page.php
的页面。因此,pages
中的这一行看起来像:
id page_name
1 admin_page.php
2 members_page.php
和auth_pages
:
au_id pages_id
1 1
1 2
也就是说auth
行admin
(au_name)可以访问admin_page.php
和members_page.php
。然后,我需要在PHP
id
中使用pages
与auth_pages
表格echo basename($_SERVER['PHP_SELF']);
交叉引用页面名称。
这是否具有实际意义?
答案 0 :(得分:1)
既然你提到它会变得简单,所以我建议你这样做。
在登录时获取用户ID,然后使用id用户运行查询
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}
现在执行上述查询并获取au_name
并将其存储在会话变量中
$_SESSION['au_name'] = {auth name from the above query} ;
创建如下函数并在登录后执行。
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
}
现在,请在登录后根据$_SESSION['au_name']
第一次进行重定向。
现在,如果用户热链接一个URL,即非管理员用户尝试访问页面,该怎么办?因此,为此创建一个名为check_access.php
的文件,并将其包含在登录页以外的所有页面中。
在此页面中,您将使用PHP获取URL并从URL获取文件名,然后检查数组$_SESSION['page_access']
上是否存在该文件名,如果是,则允许用户查看其他显示消息的页面。
确保在包含之前session_start()
。
这本质上相当简单