Introduction
在laravel
中,Policies
提供了管理授权逻辑以便控制对资源的访问权限。例如,我们可以利用poslicies
来确定当前的user
是否有修改一篇文章的权限。
生成一个PostPolicy
$ php artisan make:policy PostPlicy
生成的App/Policies/PostPolicy.php如下
<?php
namespace App\Policies;
use Illuminate\Auth\Access\HandlesAuthorization;
class PostPolicy
{
use HandlesAuthorization;
/**
* Create a new policy instance.
*
* @return void
*/
public function __construct(){
}
}
注册PostPolicy
将PostPolicy
注册到App/Providers/AuthServiceProvider
中,注意要加上注释的编号部分(I,II,III)
<?php
// App/Providers/AuthServiceProvider.php
namespace App\Providers;
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use App\Http\Models\Post; // I
use App\Policies\PostPolicy; // II
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
Post::class => PostPolicy::class, // III
];
/**
* Register any application authentication / authorization services.
*
* @param \Illuminate\Contracts\Auth\Access\Gate $gate
* @return void
*/
public function boot(GateContract $gate)
{
parent::registerPolicies($gate);
//
}
}
定义change
方法
在App/Policies/PostPolicy.php
中,定义change
方法
<?php
// App/Policies/PostPolicy.php;
namespace App\Policies;
use App\Http\Models\User;
use App\Http\Models\Post;
use Illuminate\Auth\Access\HandlesAuthorization;
class PostPolicy
{
use HandlesAuthorization;
/**
* Create a new policy instance.
*
* @return void
*/
/**
* Grant all abilities to administrator
*
* @param App\Http\Models\User $user
* @param string $ability
* @return bool
*/
public function before($user, $ability){
if(session('statut') === 'admin'){
return true;
}
}
/**
* Determine if the given post can be changed by current user
*
* @param App\Http\Models\User $user
* @param App\Http\Models\Post $post
* @return bool
*/
public function change($user, $post){
return $user->user()->id === $post->user_id;
}
}
注意:
1.因为laravel5.1的多用户验证用的是Kbwebs/MultiAuth
的,所以,在所有的$user->
后面都要加上user()
,包括Auth::
。
2.官方文档中是这样写的
public function update(User $user, Post $post)
{
return $user->id === $post->user_id;
}
在update
方法中写上了User和Post类,其实写上反而提示错误,不写是对的
3.如果想给adminstrator
所有的权限,只需要在PostPolicy.php
中添加before
方法
如上面所示
控制器验证Policies
<?php
// App/Http/Controllers/Home/BlogController.php
namespace App\Http\Controllers\Home;
use Illuminate\Http\Request;
use App\Policies\PostPolicy;
use App\Http\Controllers\Controller;
use App\Repositories\BlogRepository;
/**
* Create BlogRepository instance
*
* @var App\Repositories\BlogRepository
*/
protected $blog_gestion;
/**
* Create a new BlogController instance.
*
* @param App\Repositories\UserRepository $uesr_gestion
* @param App\Repositories\BlogRepository $blog_gestion
* @return void
*/
public function __construct(UserRepository $user_gestion, BlogRepository $blog_gestion){
$this->user_gestion = $user_gestion;
$this->blog_gestion = $blog_gestion;
$this->middleware('admin', ['only' => 'updateSeen']);
$this->middleware('ajax', ['only'=> ['updateSeen', 'updateActive']]);
}
/**
* Update "active" for the specified resource in storage
*
* @param Illuminate\Http\Request $request
* @param int $id
* @return Response
*/
public function updateActive(Request $request, $id){
$post = $this->blog_gestion->getById($id);
// authorize验证当前用户是否有修改此文章的权限,如果没有,则返回403 Forbidden
$this->authorize('change', $post);
$this->blog_gestion->updateActive($request->all(), $id);
return response()->json();
}
App/Repositories/BlogRepository.php
中部分代码
/**
* Update "active" in a post
*
* @param array $data
* @param int $id
* @return void
*/
public function updateActive($data, $id){
$post = $this->getById($id);
$post->active = $data['active'] == 'true';
$post->save();
}