Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 数据库的ACL实现_Php_Mysql_Sql_Database_Acl - Fatal编程技术网

Php 数据库的ACL实现

Php 数据库的ACL实现,php,mysql,sql,database,acl,Php,Mysql,Sql,Database,Acl,我正在尝试在数据库中实现ACL。我有一个数据库,看起来像: SYS_USERS { id, name, .. } AUTH { au_id, au_name, .. } USER_GROUPS { sys_users_id, auth_id } // bridge table au_id au_name ... 1 admin ... 2 staff ... ... ... ... id

我正在尝试在数据库中实现ACL。我有一个数据库,看起来像:

SYS_USERS { id, name, .. }
AUTH { au_id, au_name, .. }
USER_GROUPS { sys_users_id, auth_id } // bridge table
au_id    au_name    ...
    1      admin    ...
    2      staff    ...
  ...        ...    ...
id           page_name        
 1      admin_page.php
 2    members_page.php
然后说
AUTH
数据如下所示:

SYS_USERS { id, name, .. }
AUTH { au_id, au_name, .. }
USER_GROUPS { sys_users_id, auth_id } // bridge table
au_id    au_name    ...
    1      admin    ...
    2      staff    ...
  ...        ...    ...
id           page_name        
 1      admin_page.php
 2    members_page.php
我的问题是,如何从
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';
}                  
但这似乎相当“硬编码”,即如果我们要扩展系统以获得更多的
AUTH
角色,我们需要在上面添加更多的
if/ELSEIF
语句

有人能把我引向正确的方向吗

谢谢

编辑
所以我在想一种新的方法。我可以再添加两个数据库表:

PAGES { id, page_name .. }
AUTH_PAGES { au_id, pages_id, .. } // bridge between auth and pages
然后,在
页面
中,我可以存储
页面名称
,其中包含查看该页面所需的身份验证级别

例如:
名为
admin\u page.php
的页面只能由管理员访问。因此,
页面中的这一行看起来像:

SYS_USERS { id, name, .. }
AUTH { au_id, au_name, .. }
USER_GROUPS { sys_users_id, auth_id } // bridge table
au_id    au_name    ...
    1      admin    ...
    2      staff    ...
  ...        ...    ...
id           page_name        
 1      admin_page.php
 2    members_page.php
验证页面

au_id    pages_id
    1           1
    1           2
也就是说,
auth
admin
(au\u名称)可以访问
admin\u page.php
members\u page.php
。然后,我在
PHP
中需要做的就是使用
echobasename($_SERVER['PHP_SELF')将
pages
表中的
id
auth_pages
表交叉引用页面名称


这有什么实际意义吗?

既然你提到了这将很简单,所以我可以给你提个建议

登录时获取用户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}
$_SESSION['au_name'] = {auth name from the above query} ;
现在执行上述查询并获取
au\u名称
,并将其作为
存储在会话变量中

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}
$_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
}
现在,在登录后第一次根据
$\u会话['au\u name']
执行重定向

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
}
现在,如果用户热链接URL,即非管理员用户尝试访问页面,该怎么办。为此,创建一个名为
的文件check_access.php
,并将其添加到除登录页面以外的所有页面中。

在此页面中,使用PHP获取URL并从URL获取文件名,然后检查数组
$\u会话['page\u access']
中是否存在该文件名,以及是否允许用户查看页面else show消息

确保在包含之前执行
session\u start()


这在本质上相当简单

实现类似ZEND ACL的登录机制有点棘手。。那么,您是否保留了表中不同角色可以访问的页面列表?目前没有。这是一个更好的方法吗?我计划在重定向之前使用上面的
IF-ELSE
语句进行表查找,然后通过
user\u id
会话变量在每个加载页面上再次验证(以防止用户简单地键入
。/admin.php
进入管理页面),该变量在成功登录时设置。谢谢。我已经使用角色、模块和不同的操作实现了一些复杂的身份验证系统。你可以在这里查看它的开源代码并下载代码。这可能会对您有所帮助。谢谢您的回复@AbhikChakraborty,我已经查看了您的系统,它看起来非常复杂。对于像我这样的简单小系统来说太复杂了。因此,我想探讨不同的选择。我在想一个新的方法,你能在编辑后看一下原始的帖子并告诉我你的想法吗?谢谢@AbhikChakraborty。对于我的系统来说,这似乎是最好的方法。但有一个问题是,有没有更直观的方法来验证页面?正如我们都提到过使用url中的文件名(即
admin\u page.php
),如果我们将文件名改为
admin\u page\u one.php
,会发生什么情况?然后,我们需要更改数据库表
page\u name
中的行以反映此更改。我真的看不出有什么办法。有什么想法吗?是的,这是验证文件名的一个潜在问题,如果某个文件名被更改,那么相应的数据库条目也需要更改。我的意思是我看不到任何其他的选择。一个更好的方法是为每个不同的角色(如adm_uu、sales_uu)的文件使用前缀,因此只需检查前缀,您就可以确定应该由谁访问页面。这样,您只需将前缀名称存储在表中,甚至在配置文件中存储硬代码即可。谢谢@AbhikChakraborty,我没有想到这一点,这非常直观。你帮了大忙!再次感谢。