【问题标题】:Laravel Roles and Permissions based on Role specific Ability基于角色特定能力的 Laravel 角色和权限
【发布时间】:2020-12-17 10:37:09
【问题描述】:

我有一个项目,我希望特定用户查看特定页面,该特定用户具有查看角色我的设计我制作了 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');
    }
}

索引函数应该是UserPolicy中与function view相关的函数 这是位于我的blade.php 文件中的can

@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

在策略中,当我将它链接到登录用户的角色名称时,一切正常,但如果我想将它链接到角色的能​​力,它就不起作用,所以不知道@ UserPolicy中的987654330@应该实现?

【问题讨论】:

    标签: laravel policy


    【解决方案1】:

    传递给策略的第一个参数是经过身份验证的User,而不是它的Role。我不认为它有效。也许如果您使用 EXISTS 查询重新实现。

    public function view (User $user)
    {
        return $user->roles()->whereHas('abilities', function ($ability) {
            $ability->where('name', 'view');
        })
        ->exists();
    }
    

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

    【讨论】:

      猜你喜欢
      • 2018-05-29
      • 2017-09-13
      • 2023-03-15
      • 2014-09-15
      • 1970-01-01
      • 2019-04-27
      • 2019-07-31
      • 1970-01-01
      • 2019-06-26
      相关资源
      最近更新 更多