概要
Laravel5.1.11で追加されたGateを試してみる(その2)の続き。
http://qiita.com/inaka_phper/items/c584904bb39673e2dc16
今回は以下の要件を満たすための処理を追加する。
8. 管理者権限を持ったユーザーは全投稿に対して全操作が可能
実装方法としては、Gate
のbefore
を利用して
これまで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
/**
* 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カラムの内容から判別するようにする。
/**
* 管理者権限の有無をtrue/falseで取得
* @return bool
*/
public function isAdmin()
{
return $this->admin == 1;
}
管理者の場合、無条件で全部権限を与える。
今回はPolicy関係なく全権限ありにするので、AuthServiceProvider
に追加して
大本から一括で管理者権限チェックを行う。
$ability
には定義した名前(今回ならcreate/update/delete)が入ってくるので
よくあるrole方式で編集権限、削除権限という単位で分ける場合
$ability
の内容を元に処理を分けてあげればよい。
/**
* 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を返すように変更しました。
/**
* 管理者の場合、Commentに対する権限をすべて付与
* @param $user
* @param $ability
* @return mixed
*/
public function before($user, $ability)
{
return $user->isAdmin() ? true : null;
}
両方に記述した場合の優先順位
before
はAuthServiceProvider
にもPolicy
にも書くことができる。
Policyを利用で両方書いた場合の優先順位は想像通り以下の順番。
- AuthServiceProvider@before
- Policy@before
- 通常の処理
どこかでtrue
を返したら以降の処理は走らない。
この順序を把握して、うまく使い分けてあげるとよさそうです。
次回
基本的な使い方はこれぐらいっぽいですね。
次回は複数のPolicyを走らせるっぽいallows
を試してみたいと思います。