I am trying to come up with an efficient and flexible RBAC solution for my app. I have done a little research and think I have created the following.
In my User model I have:
...
public function role() {
return $this->belongsToMany('App\Models\Role', 'user_roles');
}
public function hasRole($role) {
if($this->role->where('name', $role)->first())
return true;
}
...
And an example of usage:
Route::group(['middleware' => 'auth'], function () {
Route::get('/dashboard', function () {
if (Auth::user()->hasRole('Sales')) {
return view('dashboards/sales');
} else {
return 'Don\'t know where to send you :(';
}
});
});
Permissions are assigned to roles, but permissions are not checked in the example above. Roles are then assigned to users and a user can have many roles.
Is the way I have done things scaleable and an effective RBAC solution?
I've made some RBAC
apps, and it depends on kind of challange are you facing, e.g.
User have a role but you want a that a specific user have access to some area, like Posts
, now user can edit posts like a Moderator. The permissions approach in this case suits better than just a role approach.
Define access by a slug, the other fields can be used as a reference to Super Admin, or ironically for a Editor Role, starting now, a Editor Role plus Permission to a new "area".
public function up()
{
Schema::create('permissions', function (Blueprint $table) {
$table->increments('id')->unsigned();
$table->string('name');
$table->string('slug')->unique();
$table->string('description')->nullable();
$table->string('model')->nullable();
});
}
As example of content data,
$createUsersPermission = Permission::create([
'name' => 'Create permissions',
'slug' => 'create.permissions',
...
]);
And a example of usage:
if ($user->can('create.permissions') { // you can pass an id or slug
//
}
Personally preference, and never used Zizaco Entrust as suggested by the other folks, but it works in the same way. Also you have levels approach too.
I did a little different, I made hasRole in UserRole , not is User(does not impact too much but as per code it should be). So Here is my route :
Route::group(['middleware' => 'auth'], function () {
Route::get('/myProfile', function () {
if (App\UserRole::hasRole('ROLE_CUSTOMER',Auth::user())) {
return view('views/customer');
} else {
return 'Don\'t know where to send you :(';
}
}); });
Next Thing is, the method in my UserRole. I tried to keep it simple:
public static function hasRole($authority,$user) {
$role = Role::where('authority',$authority)->first();
$userRole = UserRole::where('role_id',$role->id)
->where('user_id',$user->id)->first();
if($userRole){
return true;
}
}
We look for the authority(ROLE_USER, ROLE_CUSTOMER etc) and $user is User Object retrieved from DB . Everything else runs as per your question/ Hope it helps! Cheers!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With