Laravel:管理员可以查看/编辑/删除所有内容,但作者只能自己操作


Laravel: Admins can see/edit/delete everything, but Authors can only their own

我的应用程序有两个角色:admin &author(顺便说一下,这里有表:rolespermissionspermission_rolerole_user,还有Eloquent models Role.phpPermission.php…在model user .php中有一个名为hasRole的方法,用于检查用户是否具有某些角色…最后,在AuthServiceProvider.php中有:

public function boot(GateContract $gate)
{
    $this->registerPolicies($gate);
    foreach ($this->getPermissions() as $permission) {
        $gate->define($permission->name, function($user) use ($permission) {
            return $user->hasRole($permission->roles); 
        });
    }
}
protected function getPermissions()
{
    return Permission::with('roles')->get();
}
无论如何,我已经创建了两个角色:admin &作者
  • 管理员应该能够查看/编辑/删除所有文章。此外,管理员应该能够创建和编辑/删除所有注册用户。
  • 作者应该只能看到/编辑/删除他自己的文章。此外,作者应该只能编辑自己的个人资料。

我不确定哪一个是最好的方式来创造这个。创建以下权限是不是一个好主意:

  • manage_users
  • edit_profile
  • manage_articles
  • edit_published_articles
  • delete_published_articles

admin角色将拥有所有这些权限,而author将只有:edit_profile edit_publishhed_articles delete_publishhed_articles

然后,在UsersController.php中的每个方法中,我将检查权限:
public function index()
{
    if (Auth::user()->can('edit_profile')) {
        if (Auth::user()->can('manage_users')) {
            $users = User::with('roles')->get();
            return view('backend.users.index', compact('users'));
        }
        $users = collect([Auth::user()]);
        return view('backend.users.index', compact('users'));
    }
    return redirect('backend');
}
public function create(User $user)
{
    if (Auth::user()->can('manage_users')) {
        $roles = Role::lists('label', 'name');
        return view('backend.users.form', compact('user', 'roles'));
    }
    return redirect('backend');
}
public function store(Requests'StoreUserRequest $request)
{
    if (Auth::user()->can('manage_users')) {
        $user = new User($request->only('name', 'email', 'password'));
        $user->save();
        $roleName = $request->input('role');
        $user->assignRole($roleName);
        session()->flash('status', 'User has been created.');
        return redirect(route('backend.users.index'));
    }
    return redirect('backend');
}
public function edit($id)
{
    if (Auth::user()->can('edit_profile')) {
        if (Auth::user()->can('manage_users')) { 
            $user = User::findOrFail($id);
            $roles = Role::lists('label', 'name');
            foreach ($user->roles as $role) {
                $roleName = $role->name;
            }
            return view('backend.users.form', compact('user', 'roles', 'roleName'));
        }
        $user = User::findOrFail($id);
        if ($user->id == Auth::user()->id) {  
            $roles = Role::lists('label', 'name');
            foreach ($user->roles as $role) {
                $roleName = $role->name;
            }
            return view('backend.users.form', compact('user', 'roles', 'roleName'));
        }
    }
    return redirect('backend');
}
// ... and so on...

但是,我很确定这不是最好的方法。也许我根本不需要拥有权限-而不是检查控制器方法中的权限,最好询问用户是否具有特定角色(if (Auth::user()->hasRole('admin'))),例如,而不是:

public function index()
{
    if (Auth::user()->can('edit_profile')) {
        if (Auth::user()->can('manage_users')) {
            $users = User::with('roles')->get();
            return view('backend.users.index', compact('users'));
        }
        $users = collect([Auth::user()]);
        return view('backend.users.index', compact('users'));
    }
    return redirect('backend');
}

我们会说:

public function index()
{
    if (Auth::user()->hasRole('admin')) {
            $users = User::with('roles')->get();
            return view('backend.users.index', compact('users'));
        }
        $users = collect([Auth::user()]);
        return view('backend.users.index', compact('users'));
}

…或者这也不是一个好方法?你会怎么做?仅仅检入控制器方法就足够了吗,或者应该有一些中间件参与其中?


既然这篇文章很长,总结一下:

我创建了两个角色:admin &author and:

  • 管理员应该能够查看/编辑/删除所有文章。此外,管理员应该能够创建和编辑/删除所有注册用户。
  • 作者应该只能看到/编辑/删除他自己的文章。此外,作者应该只能编辑自己的个人资料。

你会怎么做?

我有一些更多的角色在我的应用程序,但在基本的我做了这样的

在我的应用程序中,管理员可以做版主的所有事情,甚至更多,在模型中,我创建了这样的函数:

public function isAdmin()
{
    return $this->role == self::ROLE_ADMIN;
}
public function isModerator()
{
    return $this->role == self::ROLE_MODERATOR || $this->role == self::ROLE_ADMIN;
}

所以基本上如果你是管理员你也是版主。但是你可以根据你的角色/权限和人员创建一些其他的函数

然后我使用中间件,因为这似乎是最好的方法。

所以代码看起来像这样:

//app/http/middleware/Admin.php
namespace App'Http'Middleware;
class Admin
{
    public function handle($request, Closure $next, $guard = null)
    {   
        if (!Auth::user()->isAdmin()) {
            if ($request->ajax()) {
                return response('Unauthorized.', 401);
            } elseif (Auth::user()->isModerator()) {
                return redirect()->guest('moderate');
            } else {
                return redirect()->guest('login');
            }
        }
        return $next($request);
    }
}
//app/http/middleware/Moderate.php
namespace App'Http'Middleware;
class Moderate
{
    public function handle($request, Closure $next, $guard = null)
    {
        if (!Auth::user()->isModerator()) {
            if ($request->ajax()) {
                return response('Unauthorized.', 401);
            } else {
                return redirect()->guest('login');
            }
        }
        return $next($request);
    }
}

在内核中初始化:

protected $routeMiddleware = [
    'admin' => 'App'Http'Middleware'Admin::class,
    'moderate' => 'App'Http'Middleware'Moderate::class,
    //...
];

然后在你的控制器中你可以使用:

public function __construct()
{
    $this->middleware('auth');
    $this->middleware('admin'); //or moderate or whatever
}