Laravel 7でAuthのルーティングをカスタマイズする

<b>2020/10/25更新：Vendorディレクトリはカスタマイズせずにweb.phpで記述する方法に修正しました</b>

#§1. はじめに
Laravelでログイン機能を簡単に実装できるAuthファサードですが、その中身をいじるとなると少しハードルが上がります。

そしてLaravelのバージョンによってAuth本体のディレクトリの階層構造が異なるという難しさもあります。
フレームワークではよくあることかもしれませんが。。

ですので今回はLaravel7系において、Authのルーティングをカスタマイズした時の情報をシェアしたいと思います。
Laravelのバージョンは7.25.0を使用しています。

#§2. やること
今回の記事のスコープは以下の2点です。
　(1) ログインした時のリダイレクト先をカスタマイズする
　(2) Login画面のURLをカスタマイズする

では順番にみていきましょう。

#§3. ログインした時のリダイレクト先をカスタマイズする

Authのログインフォームからログインした後に遷移するページは'/home'というURLで、このようなダッシュボードが表示されると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675596/5fc9d840-24cf-44c9-9199-955e87fdd8f4.png)
これを投稿記事一覧画面などの任意のページに変えていきます。

##3.1 リダイレクトの処理を確認する
まずログイン後のリダイレクトの処理を確認してみましょう。
このリダイレクトを行っているのが`RedirectIfAuthenticated.php`というMiddlewareです。

```php:app/Http/Middleware/RedirectIfAuthenticated.php
class RedirectIfAuthenticated
{
    public function handle($request, Closure $next, $guard = null)
    {
        if (Auth::guard($guard)->check()) {
            return redirect(RouteServiceProvider::HOME);
        }

        return $next($request);
    }
}
```

Middlewareというのはコントローラの前後で割り込んでアクションをするものでしたね。
そしてこの中の`redirect(RouteServiceProvider::HOME);`がログイン後の遷移先を示しています。

これを`redirect('/articles');`のようにログイン後に表示させたいURLを直接指定してしまっても良いのですが、今回はこの`RouteServiceProvider::HOME`という定数をカスタマイズします。

<font color="Crimson">※注意
このHOME定数はユーザー登録時の遷移先等にも影響しますので、ログインのリダイレクト先だけ変えたい場合は逆にここでリダイレクト先を直接記述するのが良いかもしれません。</font>
<br>
ちなみに`app/Http/Controllers/Auth/LoginController.php`でもリダイレクトの処理があり、同様に`RouteServiceProvider::HOME`という記述がありますが、もしMiddlewareと異なる遷移先を指定した場合は今回記載しているMiddlewareのほうが優先されます。

##3.2 HOME定数を変更する
さて、実際に`HOME`という定数を変更してみましょう。
この`RouteServiceProvider::HOME`という定数は`RouteServiceProvider.php`の中にあります。

```php:app/Providers/RouteServiceProvider.php
class RouteServiceProvider extends ServiceProvider
{
    protected $namespace = 'App\Http\Controllers';

    /**
     * The path to the "home" route for your application.
     *
     * @var string
     */
    public const HOME = '/home';
```

この中の`public const HOME = '/home';`を
`public const HOME = '/articles';`
のように表示させたいページのURLに変更すればOKです。

<font color="Crimson">※注意
HOME定数はログイン時だけでなくユーザー登録時の画面遷移等にも影響します。
</font><br>
以上でログイン時のリダイレクトのカスタマイズ作業は完了です！

#§4. ログイン画面のURLをカスタマイズする

続いて2番目のスコープであるログイン画面のURLのカスタマイズについてみていきましょう。

Authのログインフォームの画面は「'/login'」というURLになっているかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675596/e2c38a5d-c198-a9e6-3d60-be456bdcfc8c.png)
これを今回は任意のURL「'/top'」に変えていきます。

##4.1 Authのルーティングを確認する
そもそもAuthファサードのルーティングはどのようになっているのでしょうか？
URLをカスタマイズするにはまずこれを理解する必要があります。

Laravelで主にルーティングを記載しているのは「resources/routes/web.php」ですが、
Authを実装するとweb.phpの中に次のようなコードが自動生成されているかと思います。

```php:web.php
Auth::routes();
```

しかし具体的なURLやアクションの記述は見当たらず、どうルーティングしているか分かりません。
どうやらAuthクラスの`routes()`というメソッドを探す必要がありそうです。

この`routes()`を探していくと
「vendor/laravel/framework/src/Illuminate/Support/Facades/Auth.php」の中にあります。

```php:Auth.php
    public static function routes(array $options = [])
    {
        if (! static::$app->providerIsLoaded(UiServiceProvider::class)) {
            throw new RuntimeException('In order to use the Auth::routes() method, please install the laravel/ui package.');
        }      
        static::$app->make('router')->auth($options);
    }
```

しかしここにも具体的なルーティングの記述はありません。
どうやら最後の`static::$app->make('router')->auth($options)`が正体のようで、このauthメソッドは`vendor/laravel/ui/src/AuthRouteMethods.php`の中にあります。

```php:AuthRouteMethods.php
    public function auth()
    {
        return function ($options = []) {
            // Login Routes...
            if ($options['login'] ?? true) {
                $this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
                $this->post('login', 'Auth\LoginController@login');
            }
〜後略〜
```

ようやくルーティングを記述しているところにたどり着きました。
このルーティングをカスタマイズしてしまいたいのですが、そもそもVendorディレクトリは`.gitignore`でgitの管理から除外されているので、本番環境には反映されません。
ですので`web.php`で手動で記述してしまいましょう。

##4.2 URLを変更する
では実際に`web.php`のauthのルーティングを記述していきます。

手動で記述するので`Auth::routes();`は無効にした上で、先ほどの`AuthRouteMethods.php`のルーティングを記述し、それぞれのルーティングの第一引数を任意のURLに変えてあげればOKです。

```routes/web.php
// Auth::routes(); Authの標準のルーティング(無効にする)

// AuthRouteMethods.phpのルートを手動で記述
Route::get('login', 'Auth\LoginController@showLoginForm')->name('login');
Route::post('login', 'Auth\LoginController@login');
Route::post('logout', 'Auth\LoginController@logout')->name('logout');

Route::get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
Route::post('register', 'Auth\RegisterController@register');

Route::get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
Route::post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
Route::get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
Route::post('password/reset', 'Auth\ResetPasswordController@reset')->name('password.update');
              ↑↑この部分を任意のURLに変更する
```

もしViewやControllerでそのURLを使用していれば、該当箇所のURLを併せて修正します。

以上でルーティングのカスタマイズ作業は完了になります。
お疲れさまでした！

#§5 さいごに
最後までお読みいただきありがとうございました。
今回は直接ルーティングを記述してカスタマイズを行いましたが、もしもっと良い方法等あればおっしゃってください。