LaravelのGateでロール毎に権限を分ける

# 今回設定するrole
今回はレベル0が管理者でなんでも出来るユーザー。あとは1-4まで分けようと思います。
調査の段階なので、管理者と一般ユーザーとしてレベル4が分かれているのを確認できれば良しとします。
ちなみにプロジェクト名はappとしています。各ファイルのパスの最初に出てくるところがプロジェクトの名前になってますね。

# 開発環境
Laradockです。
PHP 7.4, MySQL 8.0, Laravel 6 で実行
構築は以下の手順で実施。
バージョンはそれぞれ自分が使いたい環境に合わせる。
https://qiita.com/ryuseino/items/e0e3a77245635b7cc101


# カラム追加用のマイグレーションファイルを作成
今回はユーザーテーブルにroleを追加して、それを使ってアクセス出来るページを制御してみます。
まずはファイルを作成。

```
php artisan make:migration add_column_role_users_table --table=users
```

# 出来たファイル編集
```php:app/database/migrations/2020_07_08_103224_add_column_role_users_table.php

    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->tinyInteger('role')->default(4)->after('password')->index('index_role')->comment('ロール');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('role');
        });
    }
```

ファイル編集が終わったらmigrate実行してカラムを追加しておきます。

```
 php artisan migrate
```

# 既存のファイルの編集
今回は管理者のみが見れるadmin-onlyと一般ユーザーでも見れるuser-higherを追加。

```php:app/app/Providers/AuthServiceProvider.php

    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        // adminに許可
        Gate::define('admin-only', function ($user) {
            return ($user->role == 0);
        });
        // 一般ユーザに許可
        Gate::define('user-higher', function ($user) {
            return ($user->role <= 5);
        });
    }
```


# admin用のページ作成
今回は通常のHomeを複製してからファイル名やクラス名、読み込むviewなど変更します。
作ったファイルのパスは以下。中身は省略。基本的にhomeとなってたところをadminにしただけです。
viewの方は表示される文字列を変えておくと分かりやすくていいかも知れません。

app/app/Http/Controllers/AdminController.php
app/resources/views/admin.blade.php


# 管理者だけ見れる文字列をテンプレートに追加
ページ毎の制御ではなく、ページの内容も分けることが出来ます。
今回はHomeの方で管理者だけに表示されるメッセージを追加。


```html:app/resources/views/home.blade.php
@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Dashboard</div>

                    <div class="card-body">
                        @if (session('status'))
                            <div class="alert alert-success" role="alert">
                                {{ session('status') }}
                            </div>
                        @endif

                        You are logged in!
                        @can('admin-only')
                            <div class="alert alert-dark" role="alert">
                                管理者だけですよ
                            </div>
                        @endcan
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection
```

`@can`と`@endcan`の間が管理者のみ表示されるメッセージですね。

# ユーザーのroleを設定して確認
2つユーザー登録し、roleを片方は0(管理者)にして、もう片方は4(デフォルトのユーザーレベル)に設定。
その後それぞれのユーザーでログインします。

## localhost/home にアクセスした場合
一般ユーザー -> デフォルトのホーム画面が出る
管理者 -> 追加で管理者用の文字列が出る

## localhost/admin にアクセスした場合
一般ユーザー -> アクセス出来ない (403の画面)
管理者 -> アクセス出来る


# 参考にしたページ
以下のページが大変分かりやすかったです。
https://www.ritolab.com/entry/56

こちらはもう少し細かいところも書いてありますね。
https://readouble.com/laravel/6.x/ja/authorization.html