使用中间件获取管理员权限

时间:2018-10-23 20:32:08

标签: php laravel permissions admin middleware

当我尝试编写管理规则以阻止用户输入某些路由时,出现此错误:属性[名称]在此集合实例上不存在。

用户模型

<?php

public function roles()
{
    return $this->belongsToMany(Role::class, 'role_user', 'user_id', 'role_id');
}

public function isAdmin()
{
    if ($this->roles->name == "Admin") {
        return true;
    }
    return false;
}

管理中间件

public function handle($request, Closure $next) 
{

   if (Auth::check()) {
       if (Auth::user()->isAdmin()) {
       return $next($request);
       }
    }
    return redirect('/');
 }

路由和控制器

Route::group(['middleware' => 'admin'], function () 
{ 
    Route::get('/home', 'HomeController@index')->name('home');
});

public function __construct()
{ 
    $this->middleware('admin');  
}

2 个答案:

答案 0 :(得分:2)

模型上的roles()关系是多对多的,因此调用$this->roles返回模型的集合,而不是单个模型实例。如果要检查Admin是否是当前用户的角色之一,请尝试执行以下操作:

public function isAdmin()
{
    if ($this->roles->pluck('name')->contains('Admin')) {
        return true;
    }
    return false;
}

pluck()方法从您的集合(在本例中为名称字段)返回一个“列”数据作为新集合。 contains()方法在集合中搜索给定的值,如果集合包含该值,则返回true,否则返回false。

https://laravel.com/docs/5.7/collections#available-methods

答案 1 :(得分:2)

$this->roles返回一个Collection实例。因此您无法访问集合中的属性。那是错误。

在这种情况下,您只需要知道该用户是否是管理员即可。因此,您不必获取所有角色即可做到这一点。而且这样做的效率也较低。

所以最好的解决方案是使用exists()函数。

public function isAdmin()
{
    // is there a role which name is admin.
    if ($this->roles()->where('name', 'Admin')->exists()) {
        return true;
    }
    return false;
}