Laravel5.7でGateを試す


認証と許可でいうなら許可ですね。いろいろなやり方（表現）がありますが、とりあえず最低限。
必要に応じて追記。

## やりたいこと

* 認証（ログイン）＋Gateでルート毎にアクセスコントロール
* Viewで一般会員向けコンテンツとGold会員向けだけのコンテンツを出し分け
* Gold会員はusersテーブルにrole=1を追加

## 準備

### Laravelインストール＋.env設定

割愛。

### make:auth

とりあえず認証使うのでmake:authしておく。

```bash
php artisan make:auth
```

## モデルの準備

usersテーブル（Userモデル）にrole追加して利用します。
とりあえずintegerで1だったらGold会員とする。

```diff:App/User.php
<?php

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

class CreateUsersTable extends Migration
{
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
+           $table->integer('role');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('users');
    }
}

```

migrate実行。

```bash
php artisan migrate
```

## 会員登録

```bash
php artisan tinker

>>> $user1 = new App\User;
=> App\User {#2907}
>>> $user1->name = "user1";
=> "user1"
>>> $user1->email = "user1@test.com";
=> "user1@test.com"
>>> $user1->password = Hash::make("testtest");
=> "$2y$10$hrbAsIi..t3MXh0Gex8q2uKCWq5bqXMlEJxm8LcUxY9/fSTpcz6nG"
>>> $user1->role = 1;
=> 1
>>> $user1->save();
=> true
>>>
>>> $user2 = new App\User;
=> App\User {#2915}
>>>
>>> $user2->name = "user2";
=> "user2"
>>> $user2->email = "user2@test.com";
=> "user2@test.com"
>>> $user2->password = Hash::make("testtest");
=> "$2y$10$tqZ5Uw/MK3FnM.FkknpIt.Lm7IsE97XNi9mObi7wTWEK/dbmcz9w6"
>>> $user2->role = 2;
=> 2
>>> $user2->save();
=> true
```

## ゲートの定義

GateはPolicyファイルを個別に設定することもできるけど、AuthServiceProviderのbootに書けばとりあえず動く。
下記ではroleが1のuserをgoldに設定。

```diff:app/Providers/AuthServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
    ];

    public function boot()
    {
        $this->registerPolicies();

+       //Gateの定義
+       Gate::define('gold', function($user){
+           return $user->role == 1;
+       });
    }
}
```

## ルートの定義

まず、認証済＋Goldじゃないと通さないルート（/gold）を設定。そして誰でも見えるmemberを設定。

```php
<?php

Route::get('/', function () {
    return view('welcome');
});

//Goldだけ
Route::group(['middleware' => ['auth','can:gold']], function(){
    Route::get('/gold', 'GateController@gold');
});

//誰でも
Route::get('/member', 'GateController@member');

//make auth
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
```

## Controllerの定義

Controllerを書く。viewをreturnしてるだけ。

```php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class GateController extends Controller
{
    public function gold()
    {
        return view('gate.gold');
    }

    public function member()
    {
        return view('gate.member');
    }
}
```

## Viewの定義

Gold会員用のページ。Goldって出るだけ。

```php:gold.blade.php
@extends('layouts.app')

@section('content')
<div class="container">
    <h2>gold</h2>
</div>
@endsection
```

全員アクセスできるが、Gold会員なら特別な内容が表示される。

```php:member.blade.php
@extends('layouts.app')

@section('content')
<div class="container">
    <h2>member</h2>
    <h3>全員用コンテンツ</h3>
    <p>こんにちは。みなさん。</p>

    @can('gold')
    <h3>Gold会員用コンテンツ</h3>
    <p>こんにちは。Goldさん</p>
    @endcan

</div>
@endsection
```

## 試す

```bash
php artisan serve
```

## 参考サイト

* https://www.craneto.co.jp/archives/1264/