Laravel5.1の認可機能でユーザの権限管理をしたい

Webアプリケーションにおいてユーザの権限管理をしたい場面というのはよくあると思います。管理者だけに見せたいページや機能とかですね。どうやるのかなーと思っていろいろ調べていました。

公式を読むと、組み込みで用意されている「認証」というのがまずあって(最初から用意されているAuthControllerとかを使うやつ)、それとは別に「認可」ロジックをとりまとめる手段が用意されているのだと。ふむ。

認可 5.1 Laravel

で、こちら↓できれいにまとまっていたのでそのままでうまくいくかと思いきや、5.3と5.1では認可機能の仕様がけっこう違うみたいだったので公式を参考に試してみた。

参考にしたサイト:
Laravel5 でURLベースの権限管理をする方法 | Crane & to.

認可 5.3 Laravel

よくわからんなりに読んでみると、どうもアビリティというのを定義して、コントローラから参照するという形らしい。大規模アプリ向けにポリシーという方法もあるみたいだけどそちらは今回スルーで。

アビリティを定義してみる

アビリティは

app/Providers/AuthServiceProvider.php

で定義する。

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

        //'admin'アビリティを定義
        //levelが60以上のユーザを管理者として認可する
        $gate->define( 'admin', function ( $user ) {
                return $user->level >= 60;
        });
}

↑のように定義することでログイン中のユーザのlevelカラムが60以上かどうか(管理者かどうか)を判定する。(levelカラムがユーザレベルを表すという設計にしています)

コントローラ側の実装

今回はユーザ登録機能を管理者のみに許可したいという前提。routes.phpには下記のようにルーティングを設定している。

// ユーザ登録
Route::get('signup', 'Auth\AuthController@getRegister')->name('signup.get');
Route::post('signup', 'Auth\AuthController@postRegister')->name('signup.post');

このsignup.getというルーティングに管理者以外はアクセスできないようにしたいので、先程定義したadminアビリティをAuthControllerのgetRegisterアクションにて使用する。実際にはgetRegisterアクションはトレイトなので、コードの実体は/vendor/laravel/framework/src/Illuminate/Foundation/Auth/RegistersUsers.phpにある。

RegistersUsers.php

use Gate;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
.
.
.
public function getRegister()
{
        if(Gate::denies('admin')){
                abort(403);
        }
        return view('auth.register');
}

上記実装でテストしてみたところ、管理者以外のユーザで403エラーを捕捉できたので一応目的は達成したはず。(エラー画面はちゃんと作り込むとして)これであってるのかどうかよくわからんけど、一応想定の動きをするのでたぶんあってるということにしておきたい。ちげーよバカ、って人がいたら教えろくださいm(__)m