【问题标题】:Laravel: Admins can see/edit/delete everything, but Authors can only their ownLaravel:管理员可以查看/编辑/删除所有内容,但作者只能自己查看
【发布时间】:2016-10-31 08:06:32
【问题描述】:

我的应用有两个角色:admin & author(顺便还有表格:rolespermissions em>、permission_rolerole_user,还有Eloquent模型Role.phpPermission.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();
}

无论如何,我已经创建了两个角色:adminauthor

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

我不确定哪种方法最好。创建以下权限是否是个好主意:

  • manage_users
  • edit_profile
  • manage_articles
  • edit_published_articles
  • delete_published_articles

然后 admin 角色将拥有所有这些权限,而 author 将只有:edit_profileedit_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 & author 和:

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

你会怎么做?

【问题讨论】:

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


【解决方案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);
    }
}

在内核中初始化它:

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
}

【讨论】:

    猜你喜欢
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 2021-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    相关资源
    最近更新 更多