Bilişim dünyasına kaliteli, özgün ve Türkçe içerikler kazandırmayı hedefleyen bir platform..

friends friends friends

Yii2 Framework RBAC

Merhaba arkadaşlar bu dersimizde sizlere Yii2 Framework içinde yetkilendirme işlemleri nasıl yapılır bunu anlatmaya çalışacağım. Öncelikle Yii Framework bu yetkilendirme işlemleri için hazır bir sistem olan ve dünya genelinde başkaca yazılımlarda da kullanılan RBAC(role based access control) sistemini kullanmaktadır.

Sizlerin yapacağı işlem sadece Yii ile hazır gelen bu özelliği kurmak ve kullanmayı öğrenmek olacak. Bu RBAC sistemiyle çok büyük ve oldukça karışık yetkilendirme işlemlerinin çok kolay bir şekilde üstesinden gelebilirsiniz. Öncelikle aşağıda ki şekilde bir yetki tablonusunun üzerinden RBAC sistemini anlatmaya başlayalım.

Yukarıda ki resmi anlatmaya başlayalım: Öncelikle bir haber sitenizin olduğunu varsayalım.

  1. Haber sitesinde ki haberleri ekleme, güncelleme, okuma ve silme görevleri olacak.Bu görevleri resmin en alt tarafında Bronz Renkli görevler ile ifade edeceğiz.
  2. Daha sonra her haber yazarı sadece kendi haberlerini güncelleyebilmeli. Bu görevi yukarıda ki resmin ortasında Sarı Renkli ara görev ile ifade edeceğiz.
  3. Resmin en üst tarafında bulunan Turkuaz Renkli yetkiler var. Bronz Renkli ve Sarı Renkli görevleri, Turkuaz Renkli yetkilerin üstüne atayacağız.
  4. Son olarak bu görev, ara görev ve yetkileri kullanıcılar(user) üzerine ya da görev ve ara görevleri yetkiler üzerine parent-child şeklinde atayarak RBAC sistemini kullanmaya başlayabiliriz. Bu atama işlemlerini daha sonra veri tabanında yapacağız.

Şimdi özet olarak şunu söyleyebiliriz:

  • Admin yetkisi üzerinden ok işaretleri takip ederek gidersek, bu yetki Editör, Author(Yazar) ve Reader(Okur) yetkilerinin yapabildiği tüm görevleri yapabilir.
  • Editör yetkisi üzerinden ok işaretleri takip ederek gidersek, bu yetki Reader(Okur) yetkisinin yapabildiği tüm görevleri yapabilir aynı zamanda updatePost görevi ile tüm haberleri güncelleyebilir.
  • Author(Yazar) yetkisi üzerinden ok işaretlerini takip edersek, bu yetki Reader(Okur) yetkisinin yapabildiği tüm görevleri yapabilir. Bunun yanında updateOwnPost görevi ile sadece kendi haberlerini güncelleyebilir.

Öncelikle RBAC kullanabilmek için migration özelliği aktif olmalı. Daha sonra Mysql için C:\xampp\htdocs\kafkasuni\vendor\yiisoft\yii2\rbac\migrations\schema-mysql.sql dizininde bulunan tablo oluşturma kodlarını kullanmamız gerekiyor. Kodlar şöyle:

drop table if exists `auth_assignment`;
drop table if exists `auth_item_child`;
drop table if exists `auth_item`;
drop table if exists `auth_rule`;

create table `auth_rule`
(
   `name`                 varchar(64) not null,
   `data`                 text,
   `created_at`           integer,
   `updated_at`           integer,
    primary key (`name`)
) engine InnoDB;

create table `auth_item`
(
   `name`                 varchar(64) not null,
   `type`                 integer not null,
   `description`          text,
   `rule_name`            varchar(64),
   `data`                 text,
   `created_at`           integer,
   `updated_at`           integer,
   primary key (`name`),
   foreign key (`rule_name`) references `auth_rule` (`name`) on delete set null on update cascade,
   key `type` (`type`)
) engine InnoDB;

create table `auth_item_child`
(
   `parent`               varchar(64) not null,
   `child`                varchar(64) not null,
   primary key (`parent`, `child`),
   foreign key (`parent`) references `auth_item` (`name`) on delete cascade on update cascade,
   foreign key (`child`) references `auth_item` (`name`) on delete cascade on update cascade
) engine InnoDB;

create table `auth_assignment`
(
   `item_name`            varchar(64) not null,
   `user_id`              varchar(64) not null,
   `created_at`           integer,
   primary key (`item_name`, `user_id`),
   foreign key (`item_name`) references `auth_item` (`name`) on delete cascade on update cascade
) engine InnoDB;

Yukarıda ki kodlar MYSQL içinde çalıştırılırsa 4 adet tablo oluşturacaklar.

  • itemTable
  • itemChildTable
  • assignmentTable
  • ruleTable

Daha sonra RBAC özelliğini aktif edebilmek için common/config/main.php dosyasında aşağıdaki değişiklikleri yapmanız gerekli:

return [
// ...
'components' => [
    'authManager' => [
        'class' => 'yii\rbac\DbManager',
        //'defaultRoles' => ['guest'],
    ],
    // ...
],

Bu kodlar yardımı ile tüm hiyerarşik yapıyı oluşturmuş olduk. AuthItemChild ve AuthItem tablolarımızı doldurduk fakat kişilere yetki, ara görev ve görevlerini henüz atamadık. Yani AuthAssignment tablomuz henüz boş. Bunları da başka kodlar yardımı ile atama şansınız var fakat bu tabloyu MYSQL’e giderek kendinizin doldurmasını tavsiye ederim. AuthAssignment tablosunda userid seçip görev, ara görev ve yetki atayabilirisiniz. Zaten AuthAssignment tablosu User tablosu ile otomatik ilişkilidir. AuthAssignment tablosunu da kodlar yardımı ile atamak isterseniz bu defa aşağıdaki kodları kullanmalısınız.

$auth=Yii::$app->authManager;
$auth->assign('reader','Pete');
$auth->assign('author','Bob');
$auth->assign('editor','Alice');
$auth->assign('admin','John');

Yukarıda kullanıcıların isimlerine göre atama yaptık, istersek kullanıcı id değerlerine göre de atama yapabiliriz.

$auth=Yii::$app->authManager;
$auth->assign('reader',1);//Pete
$auth->assign('author',2);//Bob
$auth->assign('editor',3);//Alice
$auth->assign('admin',4);//John

Evet artık RBAC sistemimiz Yii Framework içinde tamamen hazır hale gelmiş oldu.Şimdi basit bir örnek yapalım.Mesela sitemde ki kullanıcı createPost(haber ekleme) görevine yetkili mi değil mi şu şekilde öğrenebiliriz.

if(Yii::$app->user->checkAccess('createPost'))
{
    //...yetkili ise burası çalışacak
    //...yukarıda ki tabloya göre admin ve author burayı görebilir.
    //...yukarıda ki tabloya göre reader ve editor burayı göremez.
}

Ya da readPost(Haber Okuma) görevine yetkili mi değil mi şu şekilde de öğrenebiliriz.

Yii::$app->user->checkAccess('readPost');//true veya false dönecek

Peki bir actionUpdatePost için yetkilendirme yapmak istersek. Örneğin updatePost işlemine yetkili değilse, işlem yapamasın:

public function actionUpdatePost()
{
 if(!Yii::$app->user->checkAccess('updatePost'))
  Yii::$app->end();
 
 // ... yetkili değilse burayı göremez.
 // ... yukarıda ki tabloya göre reader(okur) burayı göremez.
 // ... yukarıda ki tabloya göre admin,editor,author(yazar) burayı görebilir.
}

Peki sadece editor yetkili ise ve işlem yapabilsin istersek, aşağıda ki kodları kullanmamız gerekecek:

if(Yii::$app->authManager->isAssigned('editor',$userid))
{
    //...sadece editor burayı görebilir.
    //...admin, editor den üst yetkili ama burayı göremez.
}

RBAC sistemi dışında sadece kullanıcı adına göre de kısıtlama yapabilirsiniz:

if(Yii::$app->user->name === 'ahmet')
{
    //...kullanıcı adı ahmet ise burayı görebilir.
}

Ya da misafir kullanıcı için de aynı işlemleri yapabilirsiniz:

if(!Yii::$app->user->isGuest)
{
    //...misafir kullanıcı değil ise burayı görebilir.
}

Tüm bunların ardından tabloya yetki tanımları, parent-child ilişkileri ile beraber kişilere gerekli yetkileri atamayı aşağıdaki gibi yapabilirsiniz.

namespace app\commands;

use Yii;
use yii\console\Controller;

class RbacController extends Controller
{
    public function actionInit()
    {
        $auth = Yii::$app->authManager;

        // add "createPost" permission
        $createPost = $auth->createPermission('createPost');
        $createPost->description = 'Create a post';
        $auth->add($createPost);

        // add "updatePost" permission
        $updatePost = $auth->createPermission('updatePost');
        $updatePost->description = 'Update post';
        $auth->add($updatePost);

        // add "author" role and give this role the "createPost" permission
        $author = $auth->createRole('author');
        $auth->add($author);
        $auth->addChild($author, $createPost);

        // add "admin" role and give this role the "updatePost" permission
        // as well as the permissions of the "author" role
        $admin = $auth->createRole('admin');
        $auth->add($admin);
        $auth->addChild($admin, $updatePost);
        $auth->addChild($admin, $author);

        // Assign roles to users. 1 and 2 are IDs returned by IdentityInterface::getId()
        // usually implemented in your User model.
        $auth->assign($author, 2);
        $auth->assign($admin, 1);
    }
}

Yukarıdaki kodlar yardımı ile RBAC tablolarımıza gerekli Permission, Role, Assign Role eklemelerini yapabiliriz.

Kullanıcı Sign Up bölümünden yeni kullanıcı eklerken beraberinde yetkileri de eklemesi için aşağıda ki kodlar yazılabilir.

public function signup()
{
    if ($this->validate()) {
        $user = new User();
        $user->username = $this->username;
        $user->email = $this->email;
        $user->setPassword($this->password);
        $user->generateAuthKey();
        $user->save(false);

        // the following three lines were added:
        $auth = Yii::$app->authManager;
        $authorRole = $auth->getRole('author');
        $auth->assign($authorRole, $user->getId());

        return $user;
    }

    return null;
}

Bir Kullanıcının herhangibir yetkiye sahip olup olmadığını belirlemek için aşağıda ki kodları kullanabiliriz.....

if (\Yii::$app->user->can('createPost')) {
    // create post
}

if (\Yii::$app->user->can('admin')) {
    // is admin
}

Bir Rolün childrenlarını aşağıda ki kod ile alabiliriz.

$children = Yii::$app->authManager->getChildren('Admin');
foreach($children as $child){
	//echo $child->name;
}

Bir Kullanıcının bütün rollerini aşağıda ki kodlar yardımı ile alabilirsiniz.

$roles=Yii::$app->authManager->getRolesByUser(Yii::$app->user->getId());
foreach($roles as $role){
	//echo $role->name;
}

Sistemdeki tüm rolleri alabiliriz


$roles=Yii::$app->authManager->getRoles();

foreach($roles as $r=>$role){
	//$role->name
}

Controller dosyasında kullanıcıya role ekleme ve role silme işlemleri için iki adet fonksiyon:

public function assignRole($role,$id) {     
	$auth = Yii::$app->authManager;
	$items = $auth->getRoles($id);
	foreach ($items as $item) {
		$auth->revoke($auth->getRole($item->name), $id);
	}

	// assign new role to the user
	$auth->assign($role, $id);
}
public function revokeRole($id) {     
	$auth = Yii::$app->authManager;
	$items = $auth->getRoles($id);
	foreach ($items as $item) {
		$auth->revoke($auth->getRole($item->name), $id);
	}
}
//kullanımı in create in controller
$this->assignRole(Yii::$app->authManager->getRole($model->rolename),$model->id);

 Controller Dosyasında gerekli izinlerin verilmesi-1

public function behaviors()
{
	return [
		'access' => [
			'class' => AccessControl::className(),
			'only' => ['create', 'update', 'index','delete','view'],
			'rules' => [
				[
					'allow' => true,
					'actions' => ['create', 'update','index','delete'],
					'roles' => ['admin'],
				],
				[
					'allow' => true,
					'actions' => ['view'],
					'roles' => ['@'],
					'matchCallback' => function(){
						// matchCallback
					},
				],
			],
			'denyCallback' => function () {
				return Yii::$app->response->redirect(['site/login']);
			},
		],
		'verbs' => [
			'class' => VerbFilter::className(),
			'actions' => [
				'delete' => ['POST'],
				'deleteselected' => ['POST'],
			],
		],
	];
}

Controller Dosyasında gerekli izinlerin verilmesi-2

namespace app\controllers;

use yii\filters\AccessControl;
use app\filters\AccessRule;
use yii\web\Controller;

class SiteController extends Controller
{
	...
	public function behaviors()
	{
		return [
			'access' => [
			    'class' => AccessControl::className(),
			    'ruleConfig' => [
			        'class' => AccessRule::className(),
			    ],
			    'rules' => [
			        [
			            'actions' => ['create'],
			            'allow' => true,
			            'roles' => ['admin'],
			        ],
			        [
			            'actions' => ['view', 'search'],
			            'allow' => true,
			            'roles' => ['?', '*', 'admin'],
			        ],
			    ],
			],
		];
	}
	...
}

Son olarak Controller sayfasında(HaberlerController) yukarıda ki yetkilendirmelerden farklı olarak çok çeşitli izinler veya kurallar yazabilirsiniz. Bu kuralların veya izinlerin içinde yetkileri kullanabilirsiniz. Örneğin Controller içinde ki action’ları kimler görebilir ya da göremez:

<?php

class HaberlerController extends Controller
{
	//...

	public function accessRules()
	{
		return array(
			array('allow',
				'actions'=>array('view'),
				'roles'=>array('reader'),//view action'ını reader ve üst yetkileri görebilir.
			),
			array('allow',
				'actions'=>array('update'),
				'roles'=>array('updatePost'),//update action'ını updatePost görevine sahip tüm yetkiler görebilir.
			),
			array('allow',
				'actions'=>array('create','admin','index'),
				#'users'=>array('mahmut'),//create,admin,index action'larını tüm kullanıcılar görebilir.
				#'users' =>array('mahmut', 'ahmet', 'ali'),//kullanıcılardan mahmut, ahmet ve ali görebilir.
				#'users'=>array('@'),//login olan kullanıcılar görebilir.
				#'users'=>array('*'),//tüm kullanıcılar görebilir.
				'roles'=>array('admin'),//sadece admin görebilir.
			),
			array('deny',
				'actions'=>array('delete'),
				'users'=>array('*'),//delete action'ını hiçbir kullanıcı göremez
			),
		);
	}

	public function actionView($id)
	{
		//...
	}

	public function actionCreate()
	{
		//...
	}

	public function actionUpdate($id)
	{
		//...
	}

	public function actionDelete($id)
	{
		//...
	}

	public function actionIndex()
	{
		//...
	}

	public function actionAdmin()
	{
		//...
	}

	
	public function loadModel($id)
	{
		//...
	}
}
Yii2 Framework RBAC AuthManager Yii2 Yetkilendirme
0 Beğeni
Yii2 Framework
Önceki Yazı

Java'da Liste ve Değişkenleri Birleştirmek

25 Ekim 2020 tarihinde yayınlandı.
Sonraki Yazı

Yii2 Framework Kullanıcı Id ve Username

25 Ekim 2020 tarihinde yayınlandı.
arrow