Laravelでuserに権限を付与してGurdで権限アクセス制御

## 1.userテーブルに権限カラムを追加します。

```
php artisan make:migration add_column_to_users_table
```
マイグレーションファイル編集し、"adimin_id"を追加します。
```php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::table('users', function (Blueprint $table) {
            //usersテーブルに追加するカラム
            $table->foreignId('admin_id')->default(2)->constrained()->onDelete('cascade');
            
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::table('users', function (Blueprint $table) {
            //
        });
    }
};

```
このあと作成するadminsテーブルを外部キーとしている。
また、今回の仕様では
<table>
    <tr>
        <td>権限者</td>
        <td>1</td>
    </tr>
    <tr>
        <td>非権限者</td>
        <td>2</td>
    </tr>
</table>

としているため、デフォルトではadmin_idに2が登録されるように->default(2)としています。
余談ですが、->default()は->constrained()->onDelete('cascade')よりも前に書くように注意してください。

## 2.権限管理用のテーブルを作成
```
php artisan make:migration create_admins_table
```
マイグレーションファイル編集
```php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('admins', function (Blueprint $table) {
            $table->id();
            $table->string('role');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('admins');
    }
};

```

## 3.Seederの作成
adminsテーブルに値を登録
```
php artisan make:seeder AdminSeeder
```
Seederを使うには、モデルも必要なため作成する(モデルだけとりあえず作成しとおけばOK。中身は編集不要)
```
php artisan make:model Admin
```
Seederファイルを編集
```php:AdminSeeder.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\Admin;//Adminモデルクラスを使用(書き忘れ注意)

class AdminSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        //
        Admin::create([
            //id(pk):1 = 権限者
            'role' => '権限者',
        ]);

        Admin::create([
            //id(pk):2 = 非権限者
            'role' => '非権限者',
        ]);
    }
}

```

ユーザーも、権限ユーザーをSeederファイル作成して作っておくと楽です。
(Seederファイル作成手順はAdiminSeederを参考)
```php:UserSeeder
<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\User;//書き忘れ注意
use Carbon\Carbon;//現在日時取得

class UserSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        //現在日時取得
        $now = Carbon::now();

        User::create([
            'name' => '権限者',
            'email' => 'admin@admin.com',
            'email_verified_at' => $now,
            'password' => bcrypt('admin0123'),
            'admin_id' => 1,
            'comment' => 'すべてのアクセス権限を持つ管理者用のアカウントです'
        ]);
    }
}

```

## 4.Gate機能で権限設定
Gate機能を使って権限を設定します。
設定は、ファイル「…/app/Providers/AuthServiceProvider.php」に記述します。
関数bootを編集して、Gateクラスを利用して各権限設定を記述します。
```php:AuthServiceProvider.php

use Illuminate\Support\Facades\Gate;//コメントアウトされてたら解除します 

    public function boot(): void
    {


        /**
         * 権限アクセス制御
         */
        // 管理者
        Gate::define('admin', function ($user) {
            return ($user->admin_id == 1);
        });

        // 編集者
        Gate::define('public', function ($user) {
            return ($user->admin_id == 2);
        });

    }
```

## 5.ルーターに追記
```php
Route::group(['middleware' => ['auth', 'can:admin']], function () {
	Route::get('/admin', 'AdminController@index');
});
```
web.phpだと、権限なしユーザーは403ページにリダイレクトされます。
api.phpだと、権限なしユーザーはapiの処理が却下(403エラー)となります。