【问题标题】:Dynamic Allow access to different permission rules - ACL LARAVEL动态允许访问不同的权限规则 - ACL LARAVEL
【发布时间】:2017-04-12 16:50:55
【问题描述】:

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

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

没关系

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

权限是动态的,我在数据库中有表:

  • 权限
  • 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

【问题讨论】:

    标签: php laravel laravel-5 acl


    【解决方案1】:

    创建一个策略类:

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

    【讨论】:

    • 感谢您的回答。对于第一个和第二个建议,访问仍然被拒绝。第三个建议返回:“未定义变量:用户”
    • @Gislef 摆脱我建议的所有这些,而不是自己做所有这些逻辑,您可以检查包github.com/spatie/laravel-permission 它具有您需要的所有功能..
    猜你喜欢
    • 2011-08-09
    • 2020-09-08
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多