Laravelの認証機能のかゆいところに手が届く小技集

# はじめに

Laravelにはデフォルトで認証機能が用意されています。

[認証](https://readouble.com/laravel/5.7/ja/authentication.html)

`php artisan make:auth`コマンド一発でビューもルートも全部定義できて、とても便利なので自分もよく使っています。

この記事では、デフォルトの認証機能をいくつかカスタマイズしていきたいと思います。

# 前提

- Laravel version 5.7

# ログイン後のリダイレクト先のカスタマイズ

デフォルトではログインに成功すると、`/home`にリダイレクトします。

なぜデフォルトが`/home`になっているのか不明ですが（`/`のほうが一般的ではと思うけど）

リダイレクト先を変更する場合は`LoginController.php`や`RegisterController.php`や`ResetPasswordController.php`の`$redirectTo`を修正すれば変更できます。

```php:app/Http/Controllers/Auth/LoginController.php
class LoginController extends Controller
{
    protected $redirectTo = '/home';
}
```

リダイレクト先をユーザー情報などによって制御したい場合は`redirectTo()`を作成する必要があります。

```php:app/Http/Controllers/Auth/LoginController.php
class LoginController extends Controller
{
    protected function redirectTo()
    {
        if () {
           return '/path1';
        }
        return '/path';
    }
}
```

※`redirectTo()`は`$redirectTo`よりも優先されます。

# バリデーションのカスタマイズ

新規登録時のバリデーションは`RegisterController.php`に記述されています。

そのため修正箇所はわかりやすいです。

```php:app/Http/Controllers/Auth/RegisterController.php
class RegisterController extends Controller
{
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:6|confirmed',
        ]);
    }
}
```

しかし、ログイン時のバリデーションは`AuthenticatesUsers.php`に記述されています（なぜなのだろう）

```php:Illuminate\Foundation\Auth\AuthenticatesUsers.php
trait AuthenticatesUsers
{
    protected function validateLogin(Request $request)
    {
        $this->validate($request, [
            $this->username() => 'required|string',
            'password' => 'required|string',
        ]);
    }
}
```

そのため、ログイン時のバリデーションのカスタマイズをする場合は、`LoginController.php`に`validateLogin()`を定義する必要があります。

```php:app/Http/Controllers/Auth/LoginController.php
class LoginController extends Controller
{
    protected function validateLogin(Request $request)
    {
        $this->validate($request, [
            $this->username() => 'required|string|min:10',
            'password' => 'required|string',
        ]);
    }
}
```

# パスワードリセットメールのカスタマイズ

デフォルトの認証機能にはパスワードをリセットする機能もついています。

しかし、送信されてくるメールは激しめの英文です。

このメールをカスタマイズするためには、まずは通知クラスを作る必要があります。

[通知](https://readouble.com/laravel/5.7/ja/notifications.html)

`php artisan make:notification CustomPasswordReset `コマンドで通知クラスを作成したらメール送信処理を記述します。

```php:app/Notifications/CustomPasswordReset.php
<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;

class CustomPasswordReset extends Notification
{
    use Queueable;
    public $token;

    public function __construct($token)
    {
        $this->token = $token;
    }

    public function via($notifiable)
    {
        return ['mail'];
    }

    public function toMail($notifiable)
    {
        return (new MailMessage)
            ->subject('パスワードリセット')
            ->view('mail.passwordReset')
            ->action('Reset Password', url(route('password.reset', $this->token, false)));
    }

    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}
```

作成したら、`User.php`に`sendPasswordResetNotification()`を定義し、作成した通知クラスを呼ぶよう記述します。

```php:app/User.php
class User extends Authenticatable
{
    public function sendPasswordResetNotification($token)
    {
        $this->notify(new CustomPasswordReset($token));
    }
}
```

あとは、メール用のbladeを作成して完成です。

```php:resources/views/mail/passwordReset.blade.php
<p>パスワードリセットメールです</p>
<a href="{{ $actionUrl }}">{{ $actionUrl }}</a>
```

# おわりに

デフォルトの認証機能には他にも○○回パスワードを間違えたらロックする機能などもあるそうです（使ったことないですが）