خب خیلی از دوستان با توجه با اینکه تا حالا چندین مورد ازم سوال کردن این ذهنیت رو پیدا کردن که وقتی صحبت از "سطح دسترسی" میشه،باید RBAC رو پیاده سازی کنند.اما این RBAC نیاز نیست برای هر چیزی پیاده بشه،و اصلا توصیه هم نمیشه.زمانی شما باید به سراغ این معماری برید که با سطح های مختلف و در اون سطح ها کاربران و باز با دسترسی های متفاوت و گروه های زیادی سرو کار دارید.تا بعدا بشه براحتی و بدون دستکاری ساختار دیتابیس،سطح،گروه و ... اضافه بکنیذ.
اما خیلی وقتا میشه با دادن یک مشخصه به کاربر،اون رو در سطح های مختلف قرار داد.مثلا یک سیستم رو در نظر بگیرید با سطح های
- مدیریت کل سیستم
- فروشنده
- خریدار
خب اگر بخوایم در این سیستم،امکانات هر سطح رو در اختیار فقط همون سطح قرار بدیم باید مشخص کنیم که چه کاربرانی جزء کدوم یک از سطح های بالا هستند.
جدول کاربران رو با این ساختار در نظر بگیرید:
CREATE TABLE IF NOT EXISTS `tbl_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) COLLATE utf8_bin NOT NULL,
`email` varchar(255) COLLATE utf8_bin NOT NULL,
`password` varchar(255) COLLATE utf8_bin NOT NULL,
`last_login_time` datetime DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
`create_user_id` int(11) DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
`update_user_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=2 ;
این جدول هیچگونه مشخصه ایی نداره که بخوایم بفهمیم کاربر در چه سطحی قرار داره.پس نیاز داریم یک فیلد دیگه به این جدول اضافه بکنیم:
ALTER TABLE `tbl_user` ADD `level` TINYINT( 1 ) NOT NULL AFTER `last_login_time` ;
خب الان به این شکل عمل میکنیم :
- مدیریت کل سیستم،سطح 1
- فروشنده سطح 2
- خریدار سطح 3
یعنی کاربرانی که در دیتابیس،فیلد level اونها
1 هست،در نقش مدیریت کل سیستم
2 هست، در نقش فروشنده
3 هست،در نقش خریدار
موقعه ثبت نام هم فقط سطح رو در سطح 2 و 3 قرار بدید و اون رو در Rule قرار بدید تا کاربری ثبت نام نکنه با سطح 1،سطح 1 رو به صورت دستی ایجاد کنید.
حالا باید بیایم امکانات هر سطح رو فقط در اختیار کاربران همون سطح قرار بدیم.پس چیزی که لازم دارم اینکه در زمان لاگین اطلاعات کاربر لاگین شده رو ذخیره کنیم.
میایم به این روش غمل میکنیم(البته روش های دیگه ایی هم هست)
اگر کاربر تونست لاگین بکنه در کامپوننت userIdentity، رکورد پیدا شده که یک شی Active Record هست رو در یک سشن ذخیره میکنیم:
$this->setState('userInfo', $user);
این user$ اینه :
$user = Users::model()->find('LOWER(username)=?', array (
strtolower($this->username)
));
حالا چطور امکانات هر سطح رو داشته باشیم و در اختیارشون قرار بدیم ؟ یکی از روش های خیلی خوب اینکه شما برای هر سطح یک ماژول بسازید
پس برید و هرچندتا سطح که دارید،به تعداد با اسم های مشخص ماژولشون رو بسازید و بعد از ساخت نیاز دارید اونرو به برنامه معرفی کنید.بعد برید به فایل main.php جایی که ماژول Gii معرفی شده،بعد از اون ماژول هارو معرفی کنید،یعنی اسم ماژول هارو قرار بدید ( Module ID )
اینم نمونه :
'modules' => array (
// uncomment the following to enable the Gii tool
/* 'gii' => array (
'class' => 'system.gii.GiiModule',
'password' => '123',
// If removed, Gii defaults to localhost only. Edit carefully to taste.
'ipFilters' => false
),*/
'developer',
'user',
'Admin'
),
خب این ماژول ها خودشون یک برنامه های کاملی هستند به عنوان زیر برنامه،پس نگران تداخل نباشید.توجه داشته باشید که مدل هایی که در اپلیکیشن اصلی در فولر models قرار دارند در ماژول هم قابل دسترسی هستند.
هر ماژول هم به صورت پیشفرض یک فایل داره که در ریشه قرار داره کلاسی هم نام با اسم ماژول وجود داره که در اون یک متدهست به این شکل :
public function beforeControllerAction($controller, $action)
{
if(parent::beforeControllerAction($controller, $action))
{
// this method is called before any module controller action is performed
// you may place customized code here
return true;
}
else
return false;
}
این متد در هربار فراخوانی ماژول اجرا میشه و ما میتونیم چک کنیم که اگر کاربر سطح دسترسی داشت،ادامه کار رو بره.وگرنه نتونه.
به این شکل:
public function beforeControllerAction ( $controller, $action ) {
if(parent::beforeControllerAction($controller, $action)) {
if(Yii::app()->user->isGuest == false) {
if(Yii::app()->user->userInfo->level==3)
return true;
}else{
Yii::app()->controller->redirect('/signin');
}
}
else
return false;
}
اگر این ماژول رو ماژول خریدار فرض کنیم،اومدیم قبل از هرکاری چک کردیم که کاربر فعلی سطح 3 رو داره ؟ خریداره یا نه ؟ اگر بود ادامه کار رو میره وگرنه با یک صفحه خالی رو به رو میشه
حالا برید کنترلر،ویو ها و ... مخصوص هر ماژول رو بسازید و برنامه رو توسعه بدید.