LoginSignup
50
48

More than 5 years have passed since last update.

Laravel5.1.11で追加されたGateを試してみる(その1)

Last updated at Posted at 2015-09-09

概要

Laravel5.1.11でユーザー権限管理がうまくまとめられるGateがオプションで追加されたみたいなのでまずは試してみる。
該当箇所の公式ドキュメントはこちら
Authorization(公式英語)

公式ドキュメントと軽くソースを見た感じでは以下の感じかなと理解してみた。
1. routes.phpと似た要領でAuthServiceProviderにポリシーを定義できる。
2. 定義したポリシーをGateファサードを使って権限等のチェックが必要な場所で利用する。
3. Policyを使うときはUserモデルがxxxxに対して操作するポリシーをxxxxPolicyに定義するという感じ
4. ログインしていない時(Userがnull)は指定ポリシーに到達する前にfalseが返される?

オブジェクト毎の括りでPolicyファイルを分けることで
ポリシーのコードが散らばらずにまとめることができ、権限チェックロジックはapp/Policies見ればいいっていう単純な状態にしやすい所でしょうか

どんな用途に使うか

管理画面等でよくある閲覧のみ~追加編集可能等のRoleから
フロントエンドでも自分の書き込んだコメントのみ編集可能というのでも使いやすそう。

特に権限チェックが複雑になりがちな箇所や、
同じコンテンツに対してCRUDできる人が違う場合など一つのPolicyクラスにまとめやすい分メリットを感じられそうです。
権限チェックの部分が完全に分離できるだけも、テストしやすくなるので意味はあるかと思いました。
ってことで、まずはよくあるパターンを用意して使ってみる。

環境と開始前の状態

composer create-projectでLaravel5.1.12が入った状態。
今回の機能は5.1.11で追加されたものですが、bugfixですぐ5.1.12になった模様。

5.1.11へアップグレードするには

公式のアップグレードガイドを見ると早い。(英語)
http://laravel.com/docs/5.1/upgrade

今回試すサンプルの要件

ざっと作ったよくあるケースのサンプルを使って、以下の要件で利用してみる。

  1. 登録ユーザーがログインすることで「記事」を投稿できる。
  2. 自分が投稿した「記事」は編集が可能。
  3. 自分が投稿した「記事」は削除が可能。
  4. 登録ユーザーは「記事」対して「コメント」を書き込める。
  5. 自分が投稿した「コメント」は編集が可能。
  6. 自分が投稿した「コメント」は削除が可能。
  7. 自分の「記事」に投稿された他ユーザーの「コメント」は削除可能。
  8. 投稿された「記事」と「コメント」は非ログインユーザーでも閲覧は可能。
  9. 管理者権限を持ったユーザーは全投稿に対して全操作が可能

ファイル名は以下の意味で作る。
User = ユーザー
Post = 記事
Comment = コメント

まずPost(記事)から作る

まずは記事に関する部分から権限を追加する。

PostPolicyを作る

以下のコマンドでartisanを使って雛形が作れが、できるのはコンストラクタがあるのみ。
php artisan make:policy PostPolicy
ファイルはapp/Policiesに作られる。

生成された雛形に、「記事」に対する要件を満たすための以下のmethodを追加する

  1. 登録ユーザーがログインすることで「記事」を投稿できる。
  2. 自分が投稿した「記事」は編集が可能。
  3. 自分が投稿した「記事」は削除が可能。

実際のコードサンプル

PostPolicy.php
    /**
     * 1. 登録ユーザーがログインすることで「記事」を投稿できる。
     * @return bool
     */
    public function create()
    {
        return true;
    }

    /**
     * 2. 自分が投稿した「記事」は編集が可能。
     * @param User $user
     * @param Post $post
     * @return bool
     */
    public function update(User $user, Post $post)
    {
        return $user->id == $post->user_id;
    }

    /**
     * 3. 自分が投稿した「記事」は削除が可能。
     * @param User $user
     * @param Post $post
     * @return bool
     */
    public function delete(User $user, Post $post)
    {
        return $user->id == $post->user_id;
    }

PostPolicyをAuthServiceProvider設定する

AuthServiceProviderに作ったPolicyを設定する。
Policyクラスを作った場合、$policiesに追記してあげる。
keyは対象のオブジェクトクラス名で設定する必要がある。

実際のコードサンプル

AuthServiceProvider.php
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
        Post::class => PostPolicy::class,
    ];

PostPolicyを使う

今回はどんな感じに使うのか試すだけなので、シンプルにコントローラーで行う。
deniesで対象として渡したクラス名読み取り、
先ほどのAuthServiceProviderpoliciesの配列キーに設定されているPolicyを自動で読んでくれる。
こんな感じで各所に追記。

実際のコードサンプル

PostController.php
        if (Gate::denies('update', $this->post)) {
            return redirect('/post')->with('message', '編集できるのは投稿者と管理者のみです。');
        }

権限の状態によって記事の編集・削除ボタンの表示を制御する。

権限がないユーザーに編集・削除ボタンを表示しても邪魔でしかないので、
編集・削除ボタンを権限に合わせて出来るものだけ表示するようにする。
実現方法もちゃんと用意されているのでありがたく使用する。

実際のサンプルコード

index.blade.php
    @can('update', $post)
    <a href="/post/{{ $post->id }}/edit" class="btn btn-primary">
        <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> 編集
    </a>
    @endcan
    @can('delete', $post)
    <button class="btn btn-danger" data-toggle="modal" data-target="#exampleModal" data-whatever="/post/{{ $post->id }}">
        <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> 削除
    </button>
    @endcan

一緒に追加された@canを使うとphp側で使うような方法で使える。

スクショもとってみた。
「エンジニア」でログインしているので、「phper」の記事には編集削除ボタンが表示されない。

ブログ一覧.png

長くなったのでここで区切る

次回はコメント部分の実装例で書いてみる。
書いた。
Laravel5.1.11で追加されたGateを試してみる(その2)
http://qiita.com/inaka_phper/items/c584904bb39673e2dc16
その2では、複数の値をPolicyに渡すときの方法がメインです。

追々AuthServiceProviderへの定義方法や、$gate->before()Gate::allowsも試してサンプル作ってみたいと思います。

50
48
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
50
48