Laravel8のJetstreamでAPIの発行をhasTeamPermissionでコントロールする


Laravel入門中です。

今回はJetstreamのAPI Token発行を制限してみます。
あまりよくわかっていないので、この方法が適切かどうかわかりませんがとりあえずやってみました。


### 前提

- Laravel8.x
- Jetstream team版導入済み

### roleを追加

まず、teamに閲覧専用のpermissionを追加します。

app>Providers>jetstreamServideProvider.phpの

```php:jetstreamServideProvider.php
    protected function configurePermissions()
    {
        Jetstream::defaultApiTokenPermissions(['read']);

        Jetstream::role('admin', 'Administrator', [
            'create',
            'read',
            'update',
            'delete',
        ])->description('Administrator users can perform any action.');

        Jetstream::role('editor', 'Editor', [
            'read',
            'create',
            'update',
        ])->description('Editor users have the ability to read, create, and update.');
    }
```

を

```php:jetstreamServideProvider.php
    protected function configurePermissions()
    {
        Jetstream::defaultApiTokenPermissions(['read']);

        Jetstream::role('admin', 'Administrator', [
            'create',
            'read',
            'update',
            'delete',
        ])->description('Administrator users can perform any action.');

        Jetstream::role('editor', 'Editor', [
            'read',
            'create',
            'update',
        ])->description('Editor users have the ability to read, create, and update.');
		///閲覧者権限を追加
		 Jetstream::role('reader', 'Reader', [
            'read',
        ])->description('Reader only read.');
    }
```


として、閲覧だけという名目のユーザreaderを作成します。


### 日本語化

resources>lang>ja.json（ja.jsonを入れていれば）

```json:ja.json
	"Reader": "閲覧者",
    "Reader only read.": "閲覧者は閲覧のみ可能です。",
```

を追加します。


### Permissionごとに表示を変更する

resources>views>navigatiton-menu.blade.php



```php:navigatiton-menu.blade.php
@if (Laravel\Jetstream\Jetstream::hasApiFeatures())
      <x-jet-dropdown-link href="{{ route('api-tokens.index') }}">
          {{ __('API Tokens') }}
      </x-jet-dropdown-link>

@endif
```


を



```php:navigatiton-menu.blade.php
<!--APIトークンの表示／非表示-->
@if (Laravel\Jetstream\Jetstream::hasApiFeatures())

    @if(auth()->user()->hasTeamPermission(auth()->user()->currentTeam, 'create'))
           <x-jet-dropdown-link href="{{ route('api-tokens.index') }}">
                  {{ __('API Tokens') }}
           </x-jet-dropdown-link>
			@endif
    @endif
```
もう一箇所、サンドイッチ（ハンバーガー）メニュー表示時のリンクも消します。

````php:navigatiton-menu.blade.php
                <!--APIトークンの表示／非表示　サンドイッチメニュー時-->
                @if (Laravel\Jetstream\Jetstream::hasApiFeatures())
                   @if(auth()->user()->hasTeamPermission(auth()->user()->currentTeam, 'create'))
                    <x-jet-responsive-nav-link href="{{ route('api-tokens.index') }}" :active="request()->routeIs('api-tokens.index')">
                        {{ __('API Tokens') }}
                    </x-jet-responsive-nav-link>
                    @endif
                @endif
```
に変更します。

これで、createのパーミッションを持たないユーザにはAPIトークンが勝手に発行されないようになりました。

### はまりポイント

roleのadminとかeditorでは指定できず、editとかcreateとかのpermissionで指定したらうまくいきました。

#### 使えない例

`@if(auth()->user()->hasTeamPermission($team, 'admin'))`

`@if(auth()->user()->hasTeamPermission($team, 'editor'))`



#### 使える例

`@if(auth()->user()->hasTeamPermission($team, 'create'))`

となります。
この場合、**create**のpermissionを持つ**adminとeditorが**Tokenを作成できます。


### これだけでは対策不十分
~~これはbladeの見え方を変えただけなので、URL直打ちですとAPI TOKEN発行ページに行ける可能性がありますので、routeでも認証を持たせることが必要かと思います~~

下に追記しました。

### URL直打ちでのToken発行を禁止する

vendor/laravel/jeststream/src/Http/COntrollers/Livewire/ApiTokenController.php


```php:ApiTokenController.php
    public function index(Request $request)
    {
		
		
        return view('api.index', [
            'request' => $request,
            'user' => $request->user(),
        ]);
    }
```

を

```php:ApiTokenController.php
    public function index(Request $request)
    {
		
				//Token発行ページへのURL直打ちを抑制
				$team = auth()->user()->currentTeam;
				if(auth()->user()->hasTeamPermission($team, 'create')){
                return view('api.index', [
		            'request' => $request,
					'user' => $request->user(),
					]);
				}else{
					return redirect('/dashboard');
				}
    }
```

として、createのpermissionを持たないユーザは/dashboardに飛ばします。