alessandrominoccheri / userpermissions
这是一个 cakephp3 插件,允许用户组或单个用户查看特定页面。
Requires
- php: >=7.0
- ext-curl: *
- composer/installers: *
Requires (Dev)
- cakephp/cakephp: >=3.0.0 <4.0.0
- cakephp/cakephp-codesniffer: dev-master
- phpunit/phpunit: *
README
这是一个 cakephp3 插件,允许用户组或单个用户查看特定页面。
背景
在 cakephp 中,管理用户或用户组查看页面的权限可能比较困难,或者你需要进行多次检查才能了解用户的权限。使用 UserPermissions 插件,你可以简单地以数组形式管理每个控制器中的所有页面,操作简单、直观且非常快速。
要求
- CakePHP 3.x
- PHP5.x
对于 cakephp 2.X,您可以检查版本 1.1.2 或下载此分支:https://github.com/AlessandroMinoccheri/UserPermissions/tree/cakephp2.0
安装
要在您的 cakephp 项目中安装此插件,您可以这样做
[Git 子模块]
打开控制台,进入项目根目录并运行命令
git submodule add -f https://github.com/AlessandroMinoccheri/UserPermissions.git app/Plugin/UserPermissions/.
[手动]
- 下载此文件:https://github.com/AlessandroMinoccheri/UserPermissions/archive/master.zip
- 解压下载的文件。
- 将生成的文件夹复制到
app/Plugin
- 将您刚刚复制的文件夹重命名为
UserPermissions
[Git 克隆]
在您的 Plugin
目录中输入
git clone https://github.com/AlessandroMinoccheri/UserPermissions.git UserPermissions
启用插件
在 cakephp 3.x 中,您需要在您的 app/Config/bootstrap.php 文件中启用插件
Plugin::load('UserPermissions');
您可以通过以下方式加载插件
Plugin::load('UserPermissions', ['autoload' => true]);
如果您已经使用了 Plugin::loadAll();,则此步骤不是必需的。
使用方法
您可以从所有控制器(除了 AppController)的 beforeFilter 动作中运行此插件,因为每次用户尝试加载页面时,都会检查权限以确定该用户是否有权访问下一页面。您需要在控制器中包含插件组件,如下所示
public $components = array(
'UserPermissions.UserPermissions'
);
如果您已经声明了变量 $components,您可以这样做
public $components = array(
'OtherComponent.Other',
'UserPermissions.UserPermissions',
);
在您的 action 的 beforeFilter 中,您可以设置您想要的用户组的规则。例如
$rules = array(
'user_type' => $user_type,
'redirect' => '/projects/',
'message' => 'You do not have permission to access this page',
'action' => $this->request->params['action'],
'controller' => $this,
'groups' => array(
'guest' => array('register', 'logout', 'login'),
'admin' => array('*'),
'admin-team' => array('register', 'add', 'logout', 'index', 'edit'),
'user' => array('register', 'add', 'logout', 'index')
),
'views' => array(
'edit' => 'checkEdit',
'delete' => 'checkDelete',
),
);
要运行检查函数,只需要这一行代码
$this->UserPermissions->allow($rules);
现在,每次您在这个控制器中加载页面时,插件都会检查登录用户是否有权访问下一页面。
设置
此插件中有一些您可以使用的参数
- user_type
- redirect
- message
- action
- controller
- groups
- views
user_type
这是用户的组名(或用户名,如果您通过用户名而不是用户组进行检查)。您需要将这些信息传递给插件以比较用户和您授予的权限。通常在用户表中,每个用户都有一个组字段来理解他们是管理员、普通用户等。您可以通过这种方式传递 user_type 值
public function beforeFilter () {
parent::beforeFilter();
//default user_type if not logged
$user_type = 'guest';
//if you have stored field group inside session
if($this->Session->read('is_logged')){
$auth_user = $this->Auth->user();
$user_type = $auth_user['group'];
}
//pass user type to the plugin
$rules = array(
'user_type' => $user_type,
'redirect' => '/projects/',
'message' => 'No permission',
'action' => $this->request->params['action'],
'controller' => $this,
'groups' => array(
'guest' => array('register', 'logout', 'login'),
'admin' => array('*'),
'admin-team' => array('register', 'add', 'logout', 'index', 'edit'),
'user' => array('register', 'add', 'logout', 'index')
),
'views' => array(
'edit' => 'checkEdit',
'delete' => 'checkDelete',
),
);
$this->UserPermissions->allow($rules);
}
我建议您在表中使用字段 group 并将其插入到会话中或使用函数检索此信息。如果您不想使用组字段,那不是很重要。重要的是,例如,如果您想使用字段 "username",则在数组 groups 中需要插入用户名列表而不是组列表,例如
$user_type = $this->getUsernameOfuserLogged();
$rules = array(
'user_type' => $user_type,
'redirect' => '/projects/',
'message' => 'No permission',
'action' => $this->request->params['action'],
'controller' => $this,
'groups' => array(
'guest' => array('register', 'logout', 'login'),
'user1' => array('*'),
'user2' => array('register', 'add', 'logout', 'index', 'edit'),
'user3' => array('register', 'add', 'logout', 'index')
),
'views' => array(
'edit' => 'checkEdit',
'delete' => 'checkDelete',
),
);
重定向
此参数允许您设置如果用户没有权限访问下一页面时的重定向页面。您可以设置此参数如下
'redirect' => '/projects/index',
或
'redirect' => '/products/test/1',
如果您不想使用此参数,可以将其留空或省略,如下所示
$user_type = $this->getUsernameOfuserLogged();
$rules = array(
'user_type' => $user_type,
'message' => 'No permission',
'action' => $this->request->params['action'],
'controller' => $this,
'groups' => array(
'guest' => array('register', 'logout', 'login'),
'user1' => array('*'),
'user2' => array('register', 'add', 'logout', 'index', 'edit'),
'user3' => array('register', 'add', 'logout', 'index')
),
'views' => array(
'edit' => 'checkEdit',
'delete' => 'checkDelete',
),
);
消息
此参数允许您在闪存消息会话中设置特定的消息。您可以插入您想要的字符串,也可以留空,或者如果您不想设置特定消息,可以省略ID。
操作
此参数是必需的,也是标准的。您必须始终以这种方式传递此参数
'action' => $this->request->params['action'],
您不能省略它或修改它,这是一个标准参数。
控制器
此参数是必需的,也是标准的。您必须始终以这种方式传递此参数
'controller' => $this->request->params['controller'],
您不能省略它或修改它,这是一个标准参数。
组
这是一个数组中的数组。在这个数组中,您可以创建用户组列表,以指定哪个用户组可以查看哪个页面。您可以在数组中插入组名或用户名(基于用户类型),在其中您可以指定该组可以访问的此控制器的操作,例如
'groups' => array(
'guest' => array('register', 'login'),
'admin' => array('*'),
'admin-team' => array('register', 'add', 'logout', 'index', 'edit'),
'user' => array('register', 'add', 'logout', 'index')
),
在这种情况下,您已经告诉插件
- 访客:未登录是一个标准参数,插件自动理解用户是否为访客。您指定未登录用户只能访问注册和登录视图。
- 管理员:您指定在管理员组中的用户可以访问此控制器的所有视图。星号字符*表示该用户可以访问此控制器的所有视图
- 管理员团队:您指定在管理员团队组中的用户可以访问以下视图:注册、添加、注销、索引和编辑。
- 用户:您指定在用户组中的用户可以访问以下视图:注册、注销和索引。
了解这一点很重要,您可以指定一些标准值
访客
:不是您系统的组,是插件为了理解未登录用户可以访问哪些页面而采用的标准。- 字符
*
:此字符指定该组可以访问此控制器的所有视图
如果您省略了某些用户组或例如访客,这意味着用户组或访客无法访问此控制器的任何页面。
视图
此参数是回调函数的数组。示例
'views' => array(
'edit' => 'checkEdit',
'delete' => 'checkDelete',
),
在这种情况下,您已经指定:如果下一个页面是编辑,插件将检查用户是否可以通过组数组访问该页面,然后如果用户可以访问该页面,则调用您传递的名称的函数。此函数必须返回一个true
或false
值。如果返回true,则用户可以访问该页面;如果返回false,则不能访问。您调用的函数必须位于调用插件函数的控制器中,必须与您传递的字符串中的名称相同,并且必须返回一个true或false值。
示例
public function beforeFilter () {
parent::beforeFilter();
//default user_type if not logged
$user_type = 'guest';
//if you have stored filed group inside session
if($this->Session->read('is_logged')){
$auth_user = $this->Auth->user();
$user_type = $auth_user['group'];
}
//pass user type to the plugin
$rules = array(
'user_type' => $user_type,
'redirect' => '/projects/',
'message' => 'No permission',
'action' => $this->request->params['action'],
'controller' => $this,
'groups' => array(
'guest' => array('register', 'logout', 'login'),
'admin' => array('*'),
'admin-team' => array('register', 'add', 'logout', 'index', 'edit'),
'user' => array('register', 'add', 'logout', 'index')
),
'views' => array(
'edit' => 'checkEdit',
'delete' => 'checkDelete',
),
);
$this->UserPermissions->allow($rules);
}
public function checkEdit(){
$auth_user = $this->Auth->user();
$user_id = $auth_user['id'];
echo($user_id.' - '.$_GET['id']);
if($user_id == $_GET['id']){
return true;
}
else{
return false;
}
}
public function checkDelete(){
if($this->Session->read('id') == $_GET['id']){
return true;
}
else{
return false;
}
}
在这种情况下有两个回调函数:checkEdit和checkDelete。
如果您在添加页面,这些函数不会被调用。但如果您尝试访问编辑页面,在理解用户是否可以通过组数组访问该页面后,插件将调用checkEdit函数。此函数比较登录用户的ID和通过GET传递的ID,这意味着只有相同的用户可以访问该页面。如果您尝试访问另一个用户的编辑页面,将返回一个错误并重定向到另一个页面。对删除页面和checkDelete()函数也是如此。
许可证
MIT许可证(MIT)
版权所有(c)2014 Alessandro Minoccheri
特此授予任何获得此软件及其相关文档副本(以下简称“软件”)的人免费使用软件的权利,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本,并允许获得软件的人这样做,但必须遵守以下条件
上述版权声明和本许可声明应包含在软件的所有副本或实质性部分中。
本软件按“原样”提供,不提供任何形式的保证,无论是明示还是暗示,包括但不限于对适销性、特定用途适用性和非侵权的保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任承担责任,无论这些责任是基于合同、侵权或其他法律行为,以及与软件、使用或其他软件的处理有关。