shigechi-64's diary

自由・自主・自立・自尊

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

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

公式を読むと、組み込みで用意されている「認証」というのがまずあって(最初から用意されている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