LoginSignup
1
4

More than 5 years have passed since last update.

[Laravel5.7]Policyを使ってモデルに対するアクセス制御を追加する

Last updated at Posted at 2018-10-15

Laravelでモデルに対するupdate、destroyなどのメソッドに対して、アクセス制御をしたい場合がある。
よくあるのは作成した本人しか編集、削除できないようにする、といった制御。

適用までの流れ

  1. Policyを作成する
  2. Policyを登録する
  3. Policyを適用する

1. Policyを作成する

# modelに対応したPolicyではないため、一からメソッドを追加していく必要がある
$ php artisan make:policy PostPolicy

or

# modelを元にPolicyを作成する(view, create, update, deleteが作成される)
$ php artisan make:policy PostPolicy --model=Post

↓modelを元に作成した時点のPolicy
https://gist.github.com/NAKKA-K/c931d687bd177a87586f1a59a07e2712.js


Policy内のメソッドはcontrollerと対応付ける必要はない。
今回はedit, update, destroyに対して付与したいアクセス制御は同じものなので、Policy内に1つだけメソッドを定義する。
メソッドの戻り値がtrueであれば許可、falseであれば拒否になる。

app/Policy/PostPolicy.php
<?php

namespace App\Policies;

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

class PostPolicy
{
    use HandlesAuthorization;

    // Postを引数に設定することによって、サービスコンテナによって依存かいけr
    public function destructive(User $user, Post $post)
    {
        // Postを作成したユーザーのみ許可する
        return $user->id == $post->user_id;
    }
}

2. Policyを登録する

作成したPolicyをmodelに対してマッピングする。

app/Providers/AuthServiceProvider.php
/**
 * The policy mappings for the application.
 *  
 * @var array
 */
protected $policies = [
    'App\Model' => 'App\Policies\ModelPolicy',
    \App\Post::class => \App\Policies\PostPolicy::class,
];

3. Policyを適用する

今回はControllerでPolicyを適用する方法を説明する。

まず、ここのcontrollerメソッドにPolicyを適用する方法。
edit, update, destroyなど、適用させたいメソッド全てに記述する必要がある。

app/Http/Controllers/PostController.php
class PostController extends Controller
 {
     public function edit(Post $post)
     {
         // Policyのdestructiveメソッドを適用($postは第2引数にあたる)
         $this->authorize('destructive', $post);
         return view('posts.edit', ['post' => $post]);
     }

middlewareとして一括で適用する方法。

app/Http/Controllers/PostController.php
class PostController extends Controller
{
    public function __construct()
    {
        // can(Policy)の、destructiveメソッドの、postに対しての制約をmiddleware指定する。
        // edit, update, destoryに対してのみmiddlewareを適用する。
        $this->middleware('can:destructive,post')
             ->only(['edit', 'update', 'destroy']);
    }

まとめ

今回はControllerに適用する方法のみ紹介したが、middlewareをrouteから指定する方法や、Bladeに適用し、許可されない場合は表示しない、等といった制御も可能。

参照

※Policyを適用する方法は多数あるため、他の方法も知りたければ以下のURL先を参照。
日本語ドキュメント
公式ドキュメント

Laravel5.7: 認可 (記事の編集はオーナーに限る、などの制限)

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4