本文實(shí)例講述了YII2框架中使用RBAC對(duì)模塊,控制器,方法的權(quán)限控制及規(guī)則的使用。分享給大家供大家參考,具體如下:
在使用YII2中自帶的RBAC時(shí),需要先配置config/web.php:
return [
// ...
'components' => [
'authManager' => [
'class' => 'yii\rbac\DbManager',
],
// ...
],
];
如果你需要運(yùn)行yii migrate來(lái)創(chuàng)建表,那么config/console.php也需要同上面一樣配置一下。
cmd進(jìn)入項(xiàng)目目錄,運(yùn)行如下命令:
yii migrate --migrationPath=@yii/rbac/migrations
你會(huì)發(fā)現(xiàn)在數(shù)據(jù)庫(kù)中創(chuàng)建了四張表
auth_assignment 角色與用戶的關(guān)聯(lián)表
auth_item 存放角色與權(quán)限,通過(guò)type字段區(qū)分
auth_item_child 存放角色與權(quán)限的上下級(jí)關(guān)系
auth_rule 規(guī)則表,用于擴(kuò)展權(quán)限功能
為了演示,我們?cè)诳刂破飨路謩e寫(xiě)四個(gè)方法,分別用來(lái)創(chuàng)建權(quán)限,創(chuàng)建角色,指派角色,使用規(guī)則。
IndexController.php代碼如下:
?php
namespace app\controllers;
use YII;
use app\models\MyUserLogin;
use app\rbac\UserUpdSelfRule;
use app\controllers\BaseController;
class IndexController extends BaseController
{
//首頁(yè)
public function actionIndex()
{
$this->renderPartial('index');
}
//登陸
public function actionLogin()
{
if (YII::$app->request->isPost) {
$user = new MyUserLogin();
$user->load(YII::$app->request->post(), '');
if ($user->login()) {
echo '登陸成功';
} else {
echo '登陸失敗';
}
} else {
return $this->renderPartial('login');
}
}
//為了演示,這里我們添加幾條權(quán)限
public function actionPer()
{
$auth = YII::$app->authManager;
//創(chuàng)建用戶刪除權(quán)限
$per = $auth->createPermission('user/del');
$per->description = '刪除用戶';
$auth->add($per);
//創(chuàng)建用戶更新權(quán)限
$per = $auth->createPermission('user/upd');
$per->description = '更新用戶';
$auth->add($per);
//創(chuàng)建用戶添加權(quán)限
$per = $auth->createPermission('user/add');
$per->description = '添加用戶';
$auth->add($per);
//創(chuàng)建用戶查看權(quán)限
$per = $auth->createPermission('user/list');
$per->description = '查看用戶列表';
$auth->add($per);
}
//添加角色
public function actionRole()
{
$auth = YII::$app->authManager;
//添加管理員角色
$admin = $auth->createRole('admin');
$admin->description = '管理員';
$auth->add($admin);
//給管理員賦予權(quán)限
$auth->addChild($admin, $auth->getPermission('user/del'));
$auth->addChild($admin, $auth->getPermission('user/upd'));
$auth->addChild($admin, $auth->getPermission('user/add'));
$auth->addChild($admin, $auth->getPermission('user/list'));
//添加普通員工角色
$employee = $auth->createRole('employee');
$employee->description = '普通員工';
$auth->add($employee);
$auth->addChild($employee, $auth->getPermission('user/list'));
$auth->addChild($employee, $auth->getPermission('user/add'));
}
//給用戶指派角色
public function actionAssign()
{
$auth = YII::$app->authManager;
//注意這里的2是用戶的ID,即你用戶表user里的ID
//也可通過(guò)YII::$app->user->id獲取
$auth->assign($auth->getRole('admin'), 1);
$auth->assign($auth->getRole('employee'), 2);
}
//添加規(guī)則
public function actionRule()
{
$auth = YII::$app->authManager;
$rule = new UserUpdSelfRule();
$auth->add($rule);
//創(chuàng)建權(quán)限,與規(guī)則關(guān)聯(lián)
$per = $auth->createPermission('user/upd/updSelf');
$per->description = '用戶只能修改自已';
$per->ruleName = $rule->name;
$auth->add($per);
//這里,要注意,要把user/upd/updSelf權(quán)限設(shè)為user/upd的父級(jí)
//要不然,普通員工訪問(wèn)user/upd這個(gè)方法會(huì)被攔住
$auth->addChild($per, $auth->getPermission('user/upd'));
//給普通員工賦予user/upd/updSelf權(quán)限,注意我們這里并沒(méi)有給員工賦予user/upd權(quán)限
$auth->addChild($auth->getRole('employee'), $per);
}
}
我們?cè)陧?xiàng)目目錄下創(chuàng)建rbac目錄,并創(chuàng)建UserUpdSelfRule.php,來(lái)實(shí)現(xiàn)用戶只能修改自已信息的規(guī)則。
?php
//注意命名空間要跟你的目錄對(duì)應(yīng)
namespace app\rbac;
use yii\rbac\Rule;
//必須繼承自yii\rbac\Rule
class UserUpdSelfRule extends Rule
{
public $name = 'userUpdSelf';
//必須要實(shí)現(xiàn)execute方法
//$user表示用戶ID
//$item規(guī)則相關(guān)的角色或者權(quán)限
//$params傳遞過(guò)來(lái)的參數(shù)
public function execute($user, $item, $params)
{
//如果沒(méi)有設(shè)置參數(shù)ID,直接返回true
if (!isset($params['id'])) {
return true;
}
//判斷id是否是當(dāng)前用戶ID
return ($params['id'] == $user) ? true : false;
}
}
我們?cè)L問(wèn)index/per查看數(shù)據(jù)表中的變化。
訪問(wèn)index/role結(jié)果如下:
訪問(wèn)index/assign結(jié)果如下:
訪問(wèn)index/rule結(jié)果如下:
為了能夠?qū)ξ覀兊哪K,控制器,方法進(jìn)行權(quán)限控制,我們需要?jiǎng)?chuàng)建一個(gè)基類來(lái)統(tǒng)一處理,上面的控制器就是繼承自基類。
BaseController.php代碼如下:
?php
namespace app\controllers;
use YII;
use yii\web\Controller;
class BaseController extends Controller
{
//不需要驗(yàn)證的
protected $noCheckAccess = [
'index/index',
'index/per',
'index/role',
'index/assign',
'index/rule',
'index/login',
];
//不需要登陸的
protected $noLogin = [
'index/login',
];
//驗(yàn)證權(quán)限
//注意,不要把獲取模塊名,控制器名,方法名寫(xiě)到init()函數(shù)里,那樣是獲取不到的
//這個(gè)坑我已經(jīng)踩了,大家就不用再去踩了
public function beforeAction($action)
{
$mid = !empty($this->module->id) ? $this->module->id : '';
$cid = !empty($this->id) ? $this->id : '';
$aid = !empty($action->id) ? $action->id : '';
//如果模塊為basic,我們只驗(yàn)證控制器/方法
if ($mid == 'basic') {
$per = "{$cid}/{$aid}";
} else {
$per = "{$mid}/{$cid}/{$aid}";
}
if (!in_array($per, $this->noLogin)) {
if (!$this->checkOnline()) {
$this->redirect('index/login');
}
}
if (!in_array($per, $this->noCheckAccess)) {
if (!YII::$app->user->can($per)) {
die('你沒(méi)有權(quán)限');
}
}
return parent::beforeAction($action);
}
//檢查是否在線
public function checkOnline()
{
return !empty(YII::$app->user->id) ? true : false;
}
}
為了演示,我們創(chuàng)建一個(gè)UserController.php,代碼如下:
?php
namespace app\controllers;
use YII;
use app\controllers\BaseController;
class UserController extends BaseController
{
public function actionUpd()
{
$id = YII::$app->request->get('id', 0);
echo 'user id : ', YII::$app->user->id, 'br>';
//先判斷用戶有沒(méi)有只能修改自已的權(quán)限
if (YII::$app->user->can('user/upd/updSelf')) {
//然后再判斷修改ID是否與自已的ID一樣,在UserUpdSelfRule里進(jìn)行判斷
if (YII::$app->user->can('user/upd/updSelf', ['id' => $id])) {
echo '有權(quán)修改自已';
} else {
echo '不能修改除自已以外的';
}
} else {
echo '修改所有';
}
}
public function actionDel()
{
echo 'user id : ', YII::$app->user->id, 'br>';
echo 'user del';
}
public function actionList()
{
echo 'user id : ', YII::$app->user->id, 'br>';
echo 'user list';
}
public function actionAdd()
{
echo 'user id : ', YII::$app->user->id, 'br>';
echo 'user add';
}
}
我的用戶表里有兩個(gè)用戶
分別登陸這兩個(gè)用戶,然后讓他們?cè)L問(wèn)user/add,user/del,user/list,user/upd,結(jié)果如下:
admin用戶狀態(tài)如下:
test用戶狀態(tài)如下:
test之所以能夠訪問(wèn)user/upd是因?yàn)槲覀儼製ser/upd/updSelf設(shè)為了user/upd的父級(jí),如果沒(méi)有設(shè)置,這里是會(huì)被攔住的。
更多關(guān)于Yii相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Yii框架入門(mén)及常用技巧總結(jié)》、《php優(yōu)秀開(kāi)發(fā)框架總結(jié)》、《smarty模板入門(mén)基礎(chǔ)教程》、《php面向?qū)ο蟪绦蛟O(shè)計(jì)入門(mén)教程》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫(kù)操作入門(mén)教程》及《php常見(jiàn)數(shù)據(jù)庫(kù)操作技巧匯總》
希望本文所述對(duì)大家基于Yii框架的PHP程序設(shè)計(jì)有所幫助。
您可能感興趣的文章:- yii2.0框架實(shí)現(xiàn)上傳excel文件后導(dǎo)入到數(shù)據(jù)庫(kù)的方法示例
- YII2框架中日志的配置與使用方法實(shí)例分析
- YII2框架中查詢生成器Query()的使用方法示例
- YII2框架中behavior行為的理解與使用方法示例
- YII2 全局異常處理深入講解