laravel - 基于角色特定能力的 Laravel 角色和权限
问题描述
我有一个项目,我希望特定用户查看特定页面,该特定用户具有查看角色,例如我有用户 1 具有管理员角色并且管理员角色能够在我的设计中查看此页面我制作了 3 个模型用户、角色和能力
用户模型:
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password','district','area','committee','position',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function answer()
{
return $this->hasMany('App\Answer');
}
public function roles()
{
return $this->belongsToMany('App\Role');
}
public function hasRole($role)
{
if ($this->roles()->where('name', $role)->first()) {
return true;
}
return false;
}
public function assignRole($role)
{
$this->roles()->save($role);
}
}
好榜样:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
protected $fillable = ['name'];
public function abilities()
{
return $this->belongsToMany('App\Ability');
}
public function hasAbility($ability)
{
if ($this->abilities()->where('name', $ability)->first()) {
return true;
}
return false;
}
public function assignAbility($ability)
{
$this->abilities()->save($ability);
}
public function users()
{
return $this->belongsToMany('App\User');
}
}
能力模型:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Ability extends Model
{
protected $fillable = ['name'];
public function roles()
{
return $this->belongsToMany('App\Role');
}
}
这是我的用户策略:
<?php
namespace App\Policies;
use App\User;
use App\Role;
use Illuminate\Auth\Access\HandlesAuthorization;
class UserPolicy
{
use HandlesAuthorization;
public function view (Role $role)
{
return $role->hasAbility('view');
}
public function manage (User $user)
{
return true;
}
public function edit (User $user)
{
return true;
}
public function update (User $user)
{
return true;
}
public function add (User $user)
{
return true;
}
}
和政策的控制者
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use App\User;
use App\Role;
class MemberController extends Controller
{
public function index(Role $role)
{
$this->authorize('view', $role);
return view ('members.create')->with('users', User::all());
}
public function manage(User $user)
{
$this->authorize('manage', $user);
return view ('members.manage')->with('users', User::all());
}
public function edit(User $user)
{
$this->authorize('edit', $user);
return view ('members.edit')->with('user', User::all())->with('roles', Role::all());
}
public function update(Request $request, User $user)
{
$this->authorize('update', $user);
$user->roles()->sync($request->roles);
return redirect('/members/edit');
}
public function store(User $user)
{
$this->authorize('add', $user);
$this->validate(request(), [
'name' => ['required', 'string', 'max:255'],
'district' => ['required', 'string', 'max:255'],
'area' => ['required', 'string', 'max:255'],
'committee' => ['required', 'string', 'max:255'],
'position' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
$data = request()->all();
$member = new User();
$member->name = $data['name'];
$member->district = $data['district'];
$member->area = $data['area'];
$member->committee = $data['committee'];
$member->position = $data['position'];
$member->email = $data['email'];
$member->password = Hash::make($data['password']);
$member->save();
return redirect('/members/create');
}
}
index 函数应该是与function view
in相关的函数UserPolicy
,它can
位于我的 Blade.php 文件中
@can('view', \App\Role::class)
<li class="">
<a class="" href="/members/create">
<span><i class="fa fa-user-plus" aria-hidden="true"></i></span>
<span>Add Member</span>
</a>
</li>
@endcan
在策略中,当我将其链接到登录用户的角色名称时,一切正常,但如果我想将其链接到角色的能力,它就不起作用,所以关于View Function
UserPolicy 中应该如何使用的任何想法被执行?
解决方案
传递给策略的第一个参数是经过身份验证的User
,而不是它的Role
。我不认为它有效。也许如果您使用EXISTS
查询重新实现。
public function view (User $user)
{
return $user->roles()->whereHas('abilities', function ($ability) {
$ability->where('name', 'view');
})
->exists();
}
->exists()
将查询转换为EXISTS
查询,如果查询找到任何内容而无需返回任何行,它将返回一个布尔值。
https://laravel.com/docs/7.x/queries#aggregates
您可以将该逻辑放入User
方法中。
# User model
public function hasAbility($ability): bool
{
return $this->roles()->whereHas('abilities', function ($ability) {
$ability->where('name', 'view');
})
->exists();
}
public function view (User $user)
{
return $user->hasAbility('view');
}
推荐阅读
- batch-file - 如何使用 vbs 运行多个批处理并使用环境变量设置批处理文件路径?
- sql-server - 如何向 T_SQL 存储过程添加可选参数?
- javascript - React.js this2.setState 不是函数?
- r - div容器中的脚本
- node.js - 从基于文件夹的 npm 依赖项导入模块
- javascript - 如何在点列表中附加光滑的箭头?
- bash - 使用 AppleScript + bash 发送文件对象
- javascript - Highcharts:向面积折线图添加多种颜色
- mfc - 如何使用 pywinauto 自动将“.txt”文件从本地加载到 MFC 应用程序?
- c# - Web API URI 版本未按预期工作