【Laravel】Role 認可/アクセス制限

環境
Laravel9 Jetstream
Inertia Vue3

# 認可/アクセス制限

ユーザーレベルによって、表示や操作可能な範囲を制限します。

admin 表示・操作できる
user 表示・操作できない

LaravelではGate、Policyで対応
Gate シンプル
Policy 特定のモデル・アクションを認可

※事前にrole列を追記しておく

公式

https://readouble.com/laravel/9.x/ja/authorization.html

# Role 役割振り

1 admin
5 manager
9 user

数字が少ない方が権限が強い。

# Roleの追加

```php:database/migrations/create_users_table.php 
tinyInteger('role') //テーブル内に追記
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/d390f467-2153-7806-4534-f3b518afb1b5.png)


```php:app/Actions/Fortify/CreateNewUser.php
return User::create([
 ʻroleʼ => 9, 
])
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/c6e7187d-935d-e02d-8aad-74951d6f8d42.png)

User::create()でまとめて登録できるようにするため、Modelsにも追記
```php:app/Models/User.php
 protected $fillable = [
 ʻroleʼ 
]; 
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/8f7ba590-a003-293f-a4ea-a8d2a826ea12.png)

# ダミーデータ
```
php artisan make:seeder UserSeeder
```
自動生成されたフォルダに追記
```php:database/seeder/UserSeeder.php
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash; 

DB::table('users')->insert([[
        'name' => 'admin',
        'email' => 'admin@admin.com',
        'password' => Hash::make('pass123'),
        'role' => 1
    ],
    [
        'name' => 'manager',
        'email' => 'manager@manager.com',
        'password' => Hash::make('pass123'),
        'role' => 5           
    ],
    [
        'name' => 'test',
        'email' => 'test@test.com',
        'password' => Hash::make('pass123'),
        'role' => 9        
    ],
]);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/76dec232-cf2b-476a-9591-bb212cfda8d3.png)

# ダミーデータの登録

```php:database/seeder/DatabaseSeeder.php
$this->call([
     UserSeeder::class,
 ]); 
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/e715326f-bb9a-f5dd-dd78-e6a6fe5c360a.png)

```
php artisan migrate:fresh --seed
```

# Gate

認可のためのクロージャベースのシンプルなアプローチ。
Gateファサードを使用しApp\Providers\AuthServiceProviderクラスのbootメソッドで定義。

```php:App\Providers\AuthServiceProvider
use Illuminate\Support\Facades\Gate;

Gate::define('admin', function($user){
    return $user->role === 1;
});

Gate::define('manager-higher', function($user){
    return $user->role > 0 && $user->role <= 5;
});

Gate::define('user-higher', function($user){
    return $user->role > 0 && $user->role <= 9;
});
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/a84c9dcc-86cd-3b46-9813-cebe914a3b9f.png)

### ルートにGateの設定
```php:routes/web.php
Route::prefix('manager')
    ->middleware('can:manager-higher')->group(function(){
     Route::get('index', function () {
     dd('manager');
     });
}); 
```
試しにmanagerでログインし、/manager/indexで以下の表示があれば問題ありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/c393afb9-8ddf-2b71-e542-c2214dbc6738.png)

userの場合はuserの値が返ってきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/7609f96f-3426-8d35-3a05-4235d8d6c740.png)

userでログインした場合
userの値は表示されるが
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/1897674b-6427-aefe-c717-5deb614f3377.png)

managerではエラーが起こる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/c053ed14-55c0-0219-42fc-e1a136927801.png)

# カスタムエラーページ
```
php artisan vendor:publish ̶tag=laravel-errors
```
views/errorsフォルダがコピーされる

公式

https://readouble.com/laravel/9.x/ja/errors.html

生成されたファイルからカスタム可能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/a4620fd5-6a09-c5be-5ed6-b9459bfdc0ab.png)