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

时间:2016-06-28 20:24:24

标签: php laravel laravel-5 laravel-5.1 laravel-5.2

我的应用有两个角色:管理员& 作者(顺便提一下,有表格:角色权限 permission_role role_user ,有Eloquent模型 Role.php Permission.php ...在模型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

然后管理员角色将拥有所有这些权限,而作者只有: edit_profile edit_published_articles delete_published_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 & 作者和:

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

你会怎么做?

1 个答案:

答案 0 :(得分:1)

我的应用程序中有更多角色,但在基础知识方面,我就是这样做的。

在我的应用程序中,管理员可以执行主持人的所有操作,在模型用户中我更多地创建了以下功能:

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

在kernel中初始化它:

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
}