动态允许访问不同的权限规则 - ACL LARAVEL

时间:2016-11-28 20:50:44

标签: php laravel laravel-5 acl

管理员用户可以查看主页上的所有帖子并访问每个帖子的更新页面

 $gate->before(function(User $user, $ability)
    {
        if ($user->hasAnyRoles('adm') )
            return true;
    });

这没关系

但是我不知道我在政策中做错了什么,因为其他用户可以看到主页上的所有帖子但无法访问他们创建的帖子更新页面,访问被拒绝。

权限是动态的,我在DB中有表:

  • 权限
  • permission_role
  • 帖子
  • 角色
  • ROLE_USER
  • 用户

家庭控制器

<?php

namespace App\Http\Controllers;

use App\Http\Requests;
use Illuminate\Http\Request;
use App\Post;
use Gate;

class HomeController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Post $post)
    {
       $posts = $post->all();
        return view('home', compact('posts'));
    }


    public function update($idPost)
    {
        $post = Post::find($idPost);


        if(Gate::denies('update-post', $post))
            abort(403);

        return view('update-post', compact('post'));
    }  

}

类AuthServiceProvider

<?php

namespace App\Providers;

use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use App\Post;
use App\User;
use App\Permission;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [

    ];


    /**
     * Register any application authentication / authorization services.
     *
     * @param  \Illuminate\Contracts\Auth\Access\Gate  $gate
     * @return void
     */
    public function boot(GateContract $gate)
    {
        $this->registerPolicies($gate);

        $permissions = Permission::with('roles')->get();
            foreach( $permissions as $permission)
            {
                $gate->define($permission->name, function(User $user) use ($permission){
                        return $user->hasPermission($permission);
                });
            }



        $gate->before(function(User $user, $ability)
        {
            if ($user->hasAnyRoles('adm') )
                return true;
        });

    }
}

模型用户

<?php

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Permission;

class User extends Authenticatable
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    public function roles()
    {
        return $this->belongsToMany(\App\Role::class);
    }

    public function hasPermission(Permission $permission)
    {
        return $this->hasAnyRoles($permission->roles);
    }

    public function hasAnyRoles($roles)
    {
        if(is_array($roles) || is_object($roles)){
            foreach($roles as $role){
                return $roles->intersect($this->roles)->count();
            }
        }
        return $this->roles->contains('name', $roles);

    }
}

模特角色

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
   public function permissions()
   {
       return $this->belongsToMany(\App\Permission::class);
   }
}

模型权限

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Permission extends Model
{
    public function roles()
    {
        return $this->belongsToMany(\App\Role::class);      
    }
}

查看home.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
    @forelse($posts as $post)
        @can('view_post', $post)
            <h2>{{$post->title}}</h2>
            <p>{{$post->description}}</p><br>
            <p>Autor: {{$post->user->name}}</p>
            <a href="{{url("/post/$post->id/update")}}">Editar</a>
        @endcan
        <hr>
    @empty
        <p>No posts registered</p>
    @endforelse
</div>
@endsection

查看update-post.blade.php

@extends('layouts.app')

@section('content')
@can('edit_post', $post)
<div class="container">
        <h2>{{$post->title}}</h2>
        <p>{{$post->description}}</p><br>
        <p>Autor: {{$post->user->name}}</p>
@endcan
@endsection

1 个答案:

答案 0 :(得分:0)

创建一个策略类:

php artisan make:policy PostPolicy --model=Post

比你的AuthServiceProvider注册政策:

 protected $policies = [
    Post::class => PostPolicy::class,
];

比PostPolicy更新方法执行此操作:

public function update(User $user, Post $post)
{
    return $user->id === $post->user_id;
}
你在家里的控制器上弄错了。

    if(Gate::denies('update-post', $post))
    {
        abort(403);
    }

或者您可以在一行中执行相同操作:

$this->authorize('update-post', $post);

或使用can中间件:

if ($user->can('update-post', $post)) {
return view('update-post', compact('post'));
}