Laravel授权策略之用户只能编辑自己的资料
在完成对未登录用户的限制之后,接下来我们要限制的是已登录用户的操作,当 id 为 1 的用户去尝试更新 id 为 2 的用户信息时,我们应该返回一个 403 禁止访问的异常。在 Laravel 中可以使用 授权策略 (Policy) 来对用户的操作权限进行验证,在用户未经授权进行操作时将返回 403 禁止访问的异常。
我们可以使用以下命令来生成一个名为 UserPolicy 的授权策略类文件,用于管理用户模型的授权。
| 1 | php artisan make:policy UserPolicy | 
所有生成的授权策略文件都会被放置在 app/Policies 文件夹下。
让我们为默认生成的用户授权策略添加 edit方法,用于用户更新时的权限验证。
app/Policies/UserPolicy.php
| 1 | 
 | 
edit方法接收两个参数,第一个参数默认为当前登录用户实例,第二个参数则为要进行授权的用户实例。当两个 id 相同时,则代表两个用户是相同用户,用户通过授权,可以接着进行下一个操作。如果 id 不相同的话,将抛出 403 异常信息来拒绝访问。
使用授权策略需要注意以下两点:
- 我们并不需要检查 $current是不是NULL。未登录用户,框架会自动为其 所有权限 返回false;
- 调用时,默认情况下,我们 不需要 传递当前登录用户至该方法内,因为框架会自动加载当前登录用户(接着看下去,后面有例子);
接下来我们还需要在 AuthServiceProvider 类中对授权策略进行设置。AuthServiceProvider 包含了一个 policies 属性,该属性用于将各种模型对应到管理它们的授权策略上。我们需要为用户模型 User 指定授权策略 UserPolicy。
app/Providers/AuthServiceProvider.php
| 1 | 
 | 
授权策略定义完成之后,我们便可以通过在用户控制器中使用 authorize 方法来验证用户授权策略。默认的 App\Http\Controllers\Controller 类包含了 Laravel 的 AuthorizesRequests trait。此 trait 提供了 authorize方法,它可以被用于快速授权一个指定的行为,当无权限运行该行为时会抛出 HttpException。authorize 方法接收两个参数,第一个为授权策略的名称,第二个为进行授权验证的数据。
我们需要为 edit 和 update 方法加上这行:
| 1 | $this->authorize('edit', $user); | 
这里
edit是指授权类里的edit授权方法,$user对应传参edit授权方法的第二个参数。正如上面定义edit授权方法时候提起的,调用时,默认情况下,我们 不需要 传递第一个参数,也就是当前登录用户至该方法内,因为框架会自动加载当前登录用户。
书写的位置如下:
app/Http/Controllers/UsersController.php
| 1 | public function edit(User $user) | 
现在,使用 id 为 1 的用户登录,当访问 id 为 2 的用户编辑页面系统将会拒绝访问。
为了更友好的显示,建议大家都在view/errors里创建一个403.blade.php文件
再次刷新该页面则显示