我一直在尝试在我的网站用户访问机制(用PHP编写)中实现角色类模型模式。不过我有一些疑虑。以下是相关代码的简化版本:
class User
{
public $role;
public $uid;
public function setRole($role)
{
$this->role = $role;
}
}
// role classes responsible for restricted actions
class BaseRole {}
class AdminRole extends BaseRole
{
// do something adminish + log action into database (with User ID)
public function SomethingAdminish($admin_id) { }
}
$user = new User();
$user->setRole(new AdminRole());
// pass Admin ID (User ID) into method
$user->rola->SomethingAdminish($user->uid);
我看到了一些弱点:
- 将任何其他$user->uid传递到"SomethingAdminish"方法将将不正确的信息登录到我的日志系统(错误的用户ID)
如果我决定以上述方法记录其他用户信息,本质上,我必须将整个User对象作为参数传递,像这样:
$user->rola->SomethingAdminish($user);
我可能错过了一些重要的东西。你们能谈谈这个问题吗?
就我个人而言,我会设置并使用访问控制列表(ACL)模式。
"资源是受访问控制的对象。
角色是一个可以请求访问资源的对象。
简单地说,角色请求访问资源。例如,如果停车场服务员请求进入汽车,然后停车场服务员是请求角色,汽车是资源,因为访问这辆车可能不是每个人都能得到的。"
以下是ACL流的基本示例(使用上面的代码)。
// Create an ACL object to store roles and resources. The ACL also grants
// and denys access to resources.
$acl = new Acl();
// Create 2 roles.
$adminRole = new Acl_Role('admin');
$editorRole = new Acl_Role('editor');
// Add the Roles to the ACL.
$acl->addRole($adminRole)
->addRole($editorRole);
// Create an example Resource. A somethingAdminish() function in this case.
$exampleResource = new Acl_Resource('somethingAdminish');
// Add the Resource to the ACL.
$acl->add($exampleResource);
// Define the rules. admins can are allowed access to the somethingAdminish
// resource, editors are denied access to the somethingAdminish resource.
$acl->allow('admin', 'somethingAdminish');
$acl->deny('editor', 'somethingAdminish');
以下是用户对象如何与ACL 交互
// Load the User
$userID = 7;
$user = User::load($userID);
// Set the User's Role. admin in this case.
$user->setRole($adminRole);
// Query the ACL to see if this User can access the somethingAdminish resource.
if ($acl->isAllowed($user, 'somethingAdminish')){
// Call the somethingAdminish function. Eg:
somethingAdminish();
// Log the action and pass the User object in so you can take any information
// you require from the User data.
$acl->logAction('somethingAdminish', $user)
}else{
die('You dont have permission to perform the somethingAdminish action.')
}