Laravel 实现用户授权有 2 种方式,gates 和 策略。
Gates 大部分应用在模型和资源无关的地方,策略应该用在特定的模型或者资源中。
这篇笔记简单介绍策略授权的简单使用。
示例:例如有个 bbs 系统,需要有个删除个人文章的功能(文章是 statuses
表),用户只能删除自己的文章,不能删除别人的文章。
创建策略
创建策略可以使用 Laravel 的 artisan 命令
php artisan make:policy StatusPolicy
app/Policies/StatusPolicy.php
<?php
namespace App\Policies;
use App\Models\Status;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;
class StatusPolicy
{
use HandlesAuthorization;
/**
* Create a new policy instance.
*
* @return void
*/
public function __construct()
{
//
}
public function destroy(User $currentUser, Status $status)
{
return $currentUser->id === $status->user_id;
}
}
destroy
方法接收两个参数,第一个参数默认为当前登录用户实例,第二个参数则为要进行授权的用户实例。当两个 id 相同时,则代表两个用户是相同用户,用户通过授权,可以接着进行下一个操作。如果 id 不相同的话,将抛出 403 异常信息来拒绝访问。
使用授权策略需要注意以下两点:
- 我们并不需要检查
$currentUser
是不是 NULL。未登录用户,框架会自动为其 所有权限 返回 false。 - 调用时,默认情况下,我们 不需要 传递当前登录用户至该方法内,因为框架会自动加载当前登录用户。
注册策略
我们需要在 app/Providers/AuthServiceProvider.php 的 policies
中注册策略
<?php
namespace App\Providers;
use App\Models\Status;
use App\Models\User;
use App\Policies\StatusPolicy;
use App\Policies\UserPolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
Status::class => StatusPolicy::class,
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
//
}
}
通过控制器辅助函数使用策略
Laravel 为所有继承了 App\Http\Controllers\Controller
基类的控制器提供了一个有用的 authorize
方法。这个方法接收需要授权的动作和相关的模型作为参数。如果动作不被授权,authorize
方法会抛出 Illuminate\Auth\Access\AuthorizationException
异常,然后被 Laravel 默认的异常处理器转化为带有 403 状态码的 HTTP 响应:
public function destroy(Status $status)
{
$this->authorize('destroy', $status);
$status->delete();
session()->flash('success', '文章已被删除!');
return redirect()->back();
}
更多用法请参考 Laravel 官方文档
参考
https://learnku.com/docs/laravel/5.5/authorization/1310#79feca