LoginSignup
15
11

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-09-13

概要

Laravel5.1.11で追加されたGateを試してみる(その2)の続き。
http://qiita.com/inaka_phper/items/c584904bb39673e2dc16

今回は以下の要件を満たすための処理を追加する。
8. 管理者権限を持ったユーザーは全投稿に対して全操作が可能

実装方法としては、Gatebeforeを利用して
これまでPolicyで設定したチェックが走る前に、管理者権限のチェックを行い
管理者であれば常に権限あり。
管理者でなければ、引き続き通常の権限チェックが走る。
という感じになる。

beforeを使うためにLaravel 5.1.16にアップデートする

2015.9.13現在、ドキュメントにはAuthorization5.1.11以上で使えると書いてあるが
一部機能は5.1.12には含まれていないようで最新版にアップデートしないと使えないものがあったので
composer updateで5.1.16へアップデートしました。

コードを実装する。

usersテーブルに管理者フラグを追加

マイグレーションでadminカラムを追加した。
php artisan make:migration modify_users_admin_column

実際のサンプルコード

2015_09_13_053509_modify_users_admin_column.php
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function ($table) {
            $table->boolean('admin')->default(0)->after('remember_token');
        });
    }

Userに管理者か確認用のisAdminを追加する

Userオブジェクトでユーザーの管理者権限を判別するisAdminを追加。
単純にadminカラムの内容から判別するようにする。

実際のサンプルコード

User.php
    /**
     * 管理者権限の有無をtrue/falseで取得
     * @return bool
     */
    public function isAdmin()
    {
        return $this->admin == 1;
    }

管理者の場合、無条件で全部権限を与える。

今回はPolicy関係なく全権限ありにするので、AuthServiceProviderに追加して
大本から一括で管理者権限チェックを行う。

$abilityには定義した名前(今回ならcreate/update/delete)が入ってくるので
よくあるrole方式で編集権限、削除権限という単位で分ける場合
$abilityの内容を元に処理を分けてあげればよい。

実際のサンプルコード

AuthServiceProvider.php
    /**
     * Register any application authentication / authorization services.
     *
     * @param  \Illuminate\Contracts\Auth\Access\Gate  $gate
     * @return void
     */
    public function boot(GateContract $gate)
    {
        parent::registerPolicies($gate);

        // 8.管理者権限を持ったユーザーは全投稿に対して全操作が可能
        $gate->before(function ($user, $ability) {
            if ($user->isAdmin()) {
                return true;
            }
        });
    }

その他の記述方法

beforeはPolicyにも記述することができ、Policyに記述した場合はPolicy単位で事前チェック行うことができる。

2016.9.1追記
beforeはLaravel側でis_null()で判定されるため、nullを返すように変更しました。

CommentPolicy.php
    /**
     * 管理者の場合、Commentに対する権限をすべて付与
     * @param $user
     * @param $ability
     * @return mixed
     */
    public function before($user, $ability)
    {
        return $user->isAdmin() ? true : null;
    }

両方に記述した場合の優先順位

beforeAuthServiceProviderにもPolicyにも書くことができる。
Policyを利用で両方書いた場合の優先順位は想像通り以下の順番。

  1. AuthServiceProvider@before
  2. Policy@before
  3. 通常の処理

どこかでtrueを返したら以降の処理は走らない。
この順序を把握して、うまく使い分けてあげるとよさそうです。

次回

基本的な使い方はこれぐらいっぽいですね。

次回は複数のPolicyを走らせるっぽいallowsを試してみたいと思います。

15
11
2

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
15
11