Laravelの認証機能をカスタマイズしたい

## やりたいこと
1.認証条件にemailやpassword以外の条件を加えたい
2.認証後のリダイレクト先を変更したい
3.ログオン記録を残したい
4.トークンミスマッチが起きた時に「TokenMismatchException in VerifyCsrfToken」を回避したい

## 事前準備
```php:2014_10_12_000000_create_users_table.php

Schema::create('users', function (Blueprint $table) {
    $table->increments('id');
    $table->boolean('status')->default(1)->comment('利用状況(0=停止中,1=利用中)');
    $table->string('login_id', 50)->unique()->comment('ログイン用ID');
    $table->string('name', 50)->comment('お名前');
    $table->string('email', 50)->unique()->comment('メールアドレス');
    $table->string('password')->comment('パスワード');
    $table->rememberToken(); 
    $table->timestamps();
});
```
マイグレーション実行すると

```php
php artisan migrate
```
これでユーザテーブルができました。
次、
ログイン画面等はもちろん自分で作ってもいいのですが、今度は自動生成されるものを利用します。

```php
php artisan make:auth
```
最後、routes/web.phpに以下の一文が追加されます。

```php:routes/web.php
Auth::routes();
```
以上、準備完了しました。

## ログイン対象のカラムの変更
ログインフォームをカスタマイズします。

```php:resources/views/auth/login.blade.php
// 変更前
// <input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required autofocus>

// 変更後
<input id="email" type="email" class="form-control" name="username" value="{{ old('username') }}" required autofocus>
```
Laravelの認証は、デフォルトでemail＋passwordで認証を行うようになっていますが、
今度は、email或login_id＋password＋statusで認証を行いたいです。
そうする場合、LoginControllerの編集が必要です。

```php:App\Http\Controllers\Auth\LoginController.php
/**
 * [username 認証カラムの変更]
 * @return [type] [description]
 */
public function username()
{
    $username = request()->input('username');
    $field = filter_var($username, FILTER_VALIDATE_EMAIL) ? 'email' : 'login_id';
    // 利用中のみのユーザがログインできるようにします
    request()->merge([$field => $username, 'status'=> 1]);
    return $field;
}

/**
 * [credentials 認証カラムの追加 `status`]
 * @param  Request $request [description]
 * @return [type]           [description]
 */
protected function credentials(Request $request)
{
    return $request->only($this->username(), 'password', 'status');
}

/**
 * [redirectPath 認証後のリダイレクト先の変更]
 * @return [type] [description]
 */
public function redirectPath()
{
    return '/';
}
```

## ログオン記録を残したい
ログオン記録用のテーブルを作成します。

```php
php artisan make:model Log -m
```
`-m`パラメータを使うと、マイグレーションを自動的に作成されます。

```php:2014_10_12_000000_create_logs_table.php
Schema::create('logs', function (Blueprint $table) {
    $table->increments('id');
    $table->string('login_id', 50)->comment('担当者ID');
    $table->string('name', 50)->comment('担当者姓名');
    $table->string('ip', 50)->comment('IPアドレス');
    $table->string('user_agent')->comment('ユーザーエージェント');
    $table->timestamps();
});
```
“ユーザーログインした時”というイベントを作成します。

```php
php artisan make:listener LogSuccessfulLogin
```

```php:App\Listeners\LogSuccessfulLogin.php
use App\Models\Logs;

class LogSuccessfulLogin
{
    public function handle($event)
    {
        // usersテーブルのupdated_atカラムのみを更新します
        $event->user->touch();

        // ログオン記録を残します
        $model = new Logs;
        $model->login_id = \Auth::user()->login_id;
        $model->name = \Auth::user()->name;
        $model->ip = request()->ip();
        $model->agent = request()->header('User-Agent');
        $model->save();
    }
}
```

App\Providersにデフォルトで存在しているEventServiceProviderに、
LogSuccessfulLoginイベントを追加します。

```php:App\Providers\EventServiceProvider.php

protected $listen = [
    'Illuminate\Auth\Events\Login' => [
        // ログオン記録イベント
        'App\Listeners\LogSuccessfulLogin',
    ],
];
```
それで、ログオン記録を残すことができると思います。

## 「TokenMismatchException in VerifyCsrfToken」を回避したい

ログインページは長時間放置すると、セッション有効期限切れて、
「TokenMismatchException in VerifyCsrfToken」がでます。

```php:App\Exceptions\Handler.php
    public function render($request, Exception $exception)
    {
        // トークンミス
        if ($exception instanceof \Illuminate\Session\TokenMismatchException){
            return back()->withErrors([trans('auth.failed')]);
        }

        return parent::render($request, $exception);
    }
```
そうすると、エラーが発生した時に、ログインページに飛ばします。

## 最後
間違いなどがございましたら、ご指摘いただけると幸いです。