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

Using Middleware to Obtain Admin Permissions

当我尝试编写管理规则以防止用户进入特定路由时出现此错误:属性 [name] 在该集合实例上不存在。

用户模型

<?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');  
}

模型上的 roles() 关系是多对多的,所以调用 $this->roles returns 模型集合,而不是单个模型实例。如果你想检查 Admin 是否是当前用户拥有的角色之一,试试这样:

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

pluck() 方法returns "column" 将您集合中的数据(在本例中为名称字段)作为新集合。 contains() 方法在集合中搜索给定值,如果集合包含该值,则 returns 为真,否则为假。

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

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

在这种情况下你只需要知道这个用户是不是管理员。所以你不必获取所有角色来做到这一点。而且这样做效率也较低。

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

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