LoginSignup
2
2

More than 3 years have passed since last update.

Laravelで認可(Policy)

Last updated at Posted at 2020-07-26

目次

Laravelの記事一覧は下記
PHPフレームワークLaravelの使い方

Laravelバージョン

動作確認はLaravel Framework 7.19.1で行っています

認可

簡単に言うと
認証はアクセスしてきているユーザーが誰なのかを認識するもの
認可はアクセスしてきたユーザーに操作を許可するかどうかを判定するもの
です

Policyを使った認可

簡単に言うと
EloquentのModelに紐づく真偽値を返す関数(Policy)を作っておき、それを簡単に呼び出せるようにしておくようなものです

前提条件

eclipseでLaravel開発環境を構築する。デバッグでブレークポイントをつけて止める。(WindowsもVagrantもdockerも)
本記事は上記が完了している前提で書かれています
プロジェクトの作成もapacheの設定も上記で行っています

Laravelで認可(Gate)
本記事は上記が完了している前提で書かれています
今回使うカラムも上記記事で作成済みです

Policyの作成

今回は下記記事で作成したTable2というModelを使います
Laravelでデータベースを操作する(Eloquent編)

コマンドラインで
cd sample
php artisan make:policy Table2Policy --model=Models\Table2
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します
eclipseプロジェクトを右クリック→リフレッシュ
/sample/app/Policies/Table2Policy.phpが現れます

/sample/app/Policies/Table2Policy.php修正

Table2Policy.php
‥‥
    public function create(User $user)
    {
        return $user->rank >= 2;
    }

    public function update(User $user, Table2 $table2)
    {
        return $user->rank >= $table2->int_col;
    }
‥‥

createメソッドとupdateメソッドを修正しました
Policyのメソッドの第一引数は必ず、ユーザーインスタンスになります

下記7メソッドが自動的にできあがっていると思います
viewAny
view
create
update
delete
restore
forceDelete
これらはコントローラーをつくるときにphp artisan make:controller XXXController --resourceのように--resourceオプションを付けて作成したリソースコントローラーの各メソッドに対応しています

コントローラメソッド ポリシーメソッド
index viewAny
show view
create create
store create
edit update
update update
destroy delete

コントローラーのindexメソッドではPolicyのviewAnyメソッドを使ってください
コントローラーのshowメソッドではPolicyのviewメソッドを使ってください
ということです

Policyの登録

/sample/app/Providers/AuthServiceProvider.php修正

AuthServiceProvider.php
‥‥
    protected $policies = [
        'App\Models\Table2' => 'App\Policies\Table2Policy',
    ];
‥‥

$policies配列に要素を追記しました
keyがModel、valueがPolicyになります
これでLaravelアプリケーションの中でPolicyを簡単に呼び出せるようになります

Controllerにメソッド追加

(1) use文追記
use Illuminate\Support\Facades\Auth;
use App\Models\User;
use App\Models\Table2;

(2) /sample/app/Http/Controllers/SampleController.phpにgate1メソッド、gate2メソッドを追記

    public function policy1()
    {
        return view('sample.policy1');
    }

    public function policy2(Request $request)
    {
        $int_col = $request->input('int_col');

        $user = Auth::user();

        $table2 = new Table2();
        $table2->int_col = $int_col;

        if (is_null($user) || !$user->can('create', Table2::class)) {
            return redirect('sample/policy1')->withInput();
        }
        if (is_null($user) || !$user->can('update', $table2)) {
            return redirect('sample/policy1')->withInput();
        }

        $data = ['table2' => $table2];

        return view('sample.policy2', $data);

    }

Policyは$user->canで呼べます
第一引数に与えた文字列はPolicyに定義したメソッド名です
第二引数はPolicyに定義したメソッドの第二引数になります
第二引数を定義していないPolicyの場合第二引数にはクラス名を渡します
Policyの第一引数は$userになります
$user->canはPolicyが返す真偽値がそのまま戻り値になります

(2) /sample/routes/web.phpに下記を追記
Route::get('sample/policy1', 'SampleController@policy1');
Route::get('sample/policy2', 'SampleController@policy2');

viewの作成

(1) /sample/resources/views/sample/policy1.blade.php

policy1.blade.php
<html>
    <head>
        <title>sample</title>
    </head>
    <body>

        <form action="{{ url('sample/policy2') }}" method="get">
            <div>int_col<input type="text" name="int_col" value="{{ old('int_col') }}"></div>
            <input type="submit" >
        </form>

    </body>
</html>

(2) /sample/resources/views/sample/policy2.blade.php

policy2.blade.php
<html>
    <head>
        <title>sample</title>
    </head>
    <body>

        <div>
        @can('create', App\Models\Table2::class)
            can create
        @elsecan('update', $table2)
            can update
        @else
            else
        @endcan
        </div>

        <div>
        @cannot('create', App\Models\Table2::class)
            cannot create
        @elsecannot('update', $table2)
            cannot update
        @else
            else
        @endcannot
        </div>

    </body>
</html>

blade内でPolicyを使うにはcanやcannotで呼び出せます
@can@cannotを使うことで、更新ボタンを特定のユーザーにだけ表示させたり、または、逆に非表示にしてりできます

動作確認

usersテーブルのrankカラムの値を適当な値にupdateします

update users set rank = 4;

ログインします
http://localhost/laravelSample/
右上のLOGINからログインします

http://localhost/laravelSample/sample/policy1
rankを4にupdateしてので
5以上の値を入力して送信ボタンをクリックするとpolicy1にリダイレクトされ先に進めないと思います
4以下の値を入力して送信ボタンをクリックするとpolicy2に遷移できます
今回はサンプルのため入力値のエラーチェックを一切行っていないので、gate1の入力欄には数値を入れてください。数値でない場合、制御されていない型エラーになります
実際にシステムを開発するときはちゃんとエラーチェックを入れましょう
エラーチェックの実装の仕方は下記に書いてあります
Laravelで入力値エラーチェック(validate)を実装する

2
2
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
2
2