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();
    }

大步点点
191 声望14 粉丝

There are only two things you need to be a great programmer: curiosity and kindness. Everything else you can learn over time. Everything.