Laravel Policy 使用

Flyertutor發表於2018-03-30

Laravel 提供更簡單的方式來處理使用者授權動作。類似使用者認證,有 2 種主要方式來實現使用者授權:gates 和策略,我這裡主要講解下策略的使用。

文件 上面有詳細的說明,我這裡只根據自己使用過程做一個簡單的筆記。

例子:我這裡準備用編輯文章授權來做演示,在這個許可權中,只有文章所有者可以編輯,來體驗一下 Policy 如何實現它。

安裝 laravel

composer create-project --prefer-dist laravel/laravel laravel-vue "5.5.*"

建表

php artisan make:migration posts --create=posts

Schema::create('posts', function (Blueprint $table) {
  $table->increments('id');
  $table->string("title", 200);
  $table->text("content");
  $table->timestamps();
  $table->index('user_id');
});

建立 Model

php artisan make:model PostModel

# app/PostModel.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class PostModel extends Model
{
  protected $table = 'posts';
  protected $fillable = ['title', 'content', 'user_id'];
}

策略其實就是授權方案所對應的類檔案,它在 app/Policies 目錄下面,下面我用命令建立一個策略檔案。

php artisan make:policy PostPolicy

命令執行完畢之後,會生成 app/Policies/PostPolicy.php 檔案,下面我們開始編輯它。

# app/Policies/PostPolicy.php
namespace App\Policies;

use App\User;
use App\PostModel;
use Illuminate\Auth\Access\HandlesAuthorization;

class TopicPolicy
{
  use HandlesAuthorization;

  public function create(User $user)
  {
    // code
  }

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

  public function delete(User $user, PostModel $postModel)
  {
    // code
  }
}

授權策略需要註冊才能使用,在什麼地方註冊呢?laravel5.5AuthServiceProvider 中包含一個 policies 的屬性,這裡面註冊策略,下面我們看下如何註冊。

# app/Providers/AuthServiceProvider.php

namespace App\Providers;

use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

user App\PostModel;
use App\Policies\PostPolicy;

class AuthServiceProvider extends ServiceProvider
{
  protected $policies = [
    PostModel::class => PostPolicy::class,  // 注意在這裡註冊 policy
  ];

  public function boot()
  {
    $this->registerPolicies();
  }
}

註冊完畢之後,在 User 模型中有 cancant 方法來使用策略,如在 PostController 編輯時使用:

# app/Http/Controllers/PostController.php

public function create() {
  if (Auth::user()->can('create', PostModel)) { // 注意這裡的用法
    // 可以建立
  } else {
    // 無許可權
  }
}

public function update(Request $request) {
  $id = $request->input('id');
  $post = PostModel::findOrFail($id);
  if (Auth::user()->can('update', $post)) {
    // 可以編輯
  } else {
    // 無編輯許可權
  }
}

如果你想超級管理員也擁有編輯許可權的話,可以在定義策略的時候加上策略過濾器,也就是一個 before 方法:

# app/Policies/PostPolicy.php
public function before($user, $ability)
{
  if ($user->isSuperAdmin()) {
    return true;
  }
}

# app/User.php
public function isSuperAdmin()
{
  // 定義ID為1為超級管理員
  if ($this->id == 1) {
    return true;
  }
  return false;
}

balde 模板中使用 @can@cannot方法來判斷

@can('create', App\PostModel::class)
  <a href="">建立</a>
@endcan

@can("update", $post)
  <a href="">編輯</a>
@endcan

好了,這次就寫到這裡,希望此篇筆記能幫助到你。

原文地址

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章