- 生成策略类
$ php artisan make:policy UserPolicy
# 包含curd所有方法的
$ php artisan make:policy UserPolicy --model=User
- 在
AuthServiceProvider
中注册策略类, 位于app/Providers/AuthServiceProvider.php
// 方法① 通过在类变量$policies的注册
protected $policies = [
'App\Models\User' => 'App\Policies\UserPolicy',
// User::class => UserPolicy::class, // 效果同上
];
// 方法② 通过在boot()方法中注册
public function boot()
{
$this->registerPolicies();
// 修改策略自动发现的逻辑
Gate::guessPolicyNamesUsing(function ($modelClass) {
// 动态返回模型对应的名称
return 'App\Policies\\' . class_basename($modelClass) . 'Policy';
});
}
- 策略的使用
/**
* 只有管理员或用户本人才能修改。
*
* @param \App\Models\User $currentUser
* @param \App\Models\User $user
* @return \Illuminate\Auth\Access\Response|bool
*/
public function update(User $currentUser, User $user)
{
return $currentUser->can('manage_users') || $currentUser->id === $user->id;
}
- 策略的过滤
对特定用户,你可能希望通过指定的策略授权所有动作。 要达到这个目的,可以在策略中定义一个 before 方法。before 方法会在策略中其它所有方法之前执行,这样提供了一种方式来授权动作而不是指定的策略方法来执行判断。这个功能最常见的场景是授权应用的管理员可以访问所有动作:
/**
* 权限判断之前确定操作用户是否是超管
* @param User $currentUser
* @param string $ability 预备做的操作
* @return bool
*/
public function before(User $currentUser, $ability)
{
if ($currentUser->isAdmin()) {
// 只有false才会继续做权限判断
return true;
}
}
- 权限策略的使用
Laravel 应用内置的 User 模型包含 2 个有用的方法来授权动作:can 和 cant / cannot。can 方法需要指定授权的动作和相关的模型。( cant 和 cannot 处理效果是一样的, 同英语 can't 和 can not )
// controller中操作
// $this->authorize('update', $user); // 电脑的实现
// 接口返回
if (request()->user()->cant('update')) {
return response()->json(['code' => 403, 'msg' => '无权操作']);
};
注:
通过 authorize()方法操作会报出异常
处理抛出的授权异常:在app/Exceptions/Handler.php
中判断异常类型,若是授权异常,则跳转到无权限页面
/**
* Render an exception into an HTTP response.
* @param \Illuminate\Http\Request $request
* @param Exception $exception
* @return \Illuminate\Http\RedirectResponse|\Symfony\Component\HttpFoundation\Response
*/
public function render($request, Exception $exception)
{
if ($exception instanceof AuthorizationException) {
return redirect()->guest(route('admin.permission-denied'));
}
return parent::render($request, $exception);
}