laravel5.1 -- ACL(Access Control List) Policies篇

Introduction

laravel中,Policies提供了管理受權邏輯以便控制對資源的訪問權限。例如,咱們能夠利用poslicies來肯定當前的user是否有修改一篇文章的權限。php

生成一個PostPolicy

$ php artisan make:policy PostPlicy

生成的App/Policies/PostPolicy.php以下laravel

<?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)git

<?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方法github

<?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.官方文檔中是這樣寫的web

public function update(User $user, Post $post)
    {
        return $user->id === $post->user_id;
    }

update方法中寫上了User和Post類,其實寫上反而提示錯誤,不寫是對的ajax

3.若是想給adminstrator全部的權限,只須要在PostPolicy.php中添加before方法
如上面所示json

控制器驗證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中部分代碼session

/**
    * 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();
    }
相關文章
相關標籤/搜索