今回は前回作成した認証機能を少しいじってみます。主にルーティング・ビューファイル・コントローラファイルを編集し、自分で設定したルーティングや自分でデザインした認証フォームにしながら、どのページがログインの必要なページなのかを設定していきます。 今回の機能はLaravelのEloquent関連の記事の延長として解説します。LaravelのEloquent関連(レコード取得・レコード登録・レコード削除・レコード更新)を進めていない方は先に進めてから今回の記事を進めましょう。

Laravelの認証機能-実用編

3年以内に更新されました。情報が古い可能性があります。
更新日 : 2020年02月05日

今回は前回作成した認証機能を少しいじってみます。主にルーティング・ビューファイル・コントローラファイルを編集し、自分で設定したルーティング自分でデザインした認証フォームにしながら、どのページがログインの必要なページなのかを設定していきます。

今回の機能はLaravelのEloquent関連の記事の延長として解説します。LaravelのEloquent関連(レコード取得レコード登録レコード削除レコード更新)を進めていない方は先に進めてから今回の記事を進めましょう。

今回の改修内容

デフォルトの認証機能を改修していきますが 、今回は以下の改修を行ってみます。

Eloquent関連記事ではPostControllerを作成して、記事のCRUD機能を作成しました。通常のブログであれば、ブログの投稿内容は管理者のみが変更するべきです。つまりここには管理者である証明(認証機能)が必要です。

今回は認証機能をこのPostControllerに付与できるように改修していきます。

ルーティングの設定

前回作成した認証機能では以下のような認証専用ルーティングが定義されているのを確認しました。

/**
 * Register the typical authentication routes for an application.
 *
 * @param  array  $options
 * @return void
 */
public function auth(array $options = [])
{
    // Authentication Routes...
    $this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
    $this->post('login', 'Auth\LoginController@login');
    $this->post('logout', 'Auth\LoginController@logout')->name('logout');

    // Registration Routes...
    if ($options['register'] ?? true) {
        $this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
        $this->post('register', 'Auth\RegisterController@register');
    }

    // Password Reset Routes...
    if ($options['reset'] ?? true) {
        $this->resetPassword();
    }

    // Email Verification Routes...
    if ($options['verify'] ?? false) {
        $this->emailVerification();
    }
}

web.phpにはこのメソッドを呼び出すようにAuth::routes()を呼び出すことでルーティングを定義していましたが、上記のルーティング定義があれば同様のログイン機能を実装できます。

Auth::routes()を削除して、各種定義したいルーティング機能を定義しておけばOKです。web.phpに記載する場合には$this->get()ではなく、Route::get()などに変更することだけ注意しましょう。

さらに、URLを変更したい場合や、認証処理をするコントローラーを変更したい場合なども今までのルーティング定義と同様に実行するコントローラーを指定すればOKです。

今回はweb.phpに以下のようにルーティングを定義しておきます。認証コントローラーを別のクラスに変更したルーティングを定義しておきます。Auth::routes()はコメントアウト等をしておいて、以下を追加しています。

// Auth::routes();

Route::get('/home', 'HomeController@index')->name('home');

// ログイン・ログアウト
Route::get('login', 'Auth\PostLoginController@showLoginForm')->name('login');
Route::post('login', 'Auth\PostLoginController@login');
Route::post('logout', 'Auth\PostLoginController@logout')->name('logout');

// 新規登録
Route::get('register', 'Auth\PostRegisterController@showRegistrationForm')->name('register');
Route::post('register', 'Auth\PostRegisterController@register');

今回コントローラファイルの指定を変更しました。Auth\LoginController@~~Auth\PostLoginController@~~などとなっていることに注意しましょう。

コントローラファイルの追加・編集

先程ルーティングで実行するコントローラーファイルの指定を変更したものを定義しました。

認証用のコントローラーの機能は基本的にはクラスの継承を利用することで簡単に実現可能です。

今回はルーティングで設定したPostLoginControllerPostRegisterControllerを作成していきましょう。

PostLoginControllerの追加

まずはPostLoginControllerです。下記のように実装しました。LoginController.phpファイルと同様の場所のapp/Http/Controllers/Authフォルダに、PostLoginController.phpというファイル名で配置しましょう。

<?php
namespace App\Http\Controllers\Auth;

class PostLoginController extends LoginController
{

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = '/post/list';
}

たったこれだけです。クラス定義の部分class PostLoginController extends LoginControllerを見ればわかりますが、LoginControllerを継承しています。

そのためLoginControllerの機能はすべて利用可能です。そして今回は、ログイン後に遷移するべきURL$redirectToで定義しています。LoginControllerでは違うURLが定義されているので、この部分だけ上書き(オーバーライド)します。今回は/post/listとしました。

PostRegisterControllerの追加

PostRegisterControllerも同様に作成していきましょう。RegisterController.phpファイルと同様の場所のapp/Http/Controllers/Authフォルダに、PostRegisterController.phpというファイル名で配置します。

<?php
namespace App\Http\Controllers\Auth;

class PostRegisterController extends RegistersController
{
    /**
     * Where to redirect users after registration.
     *
     * @var string
     */
    protected $redirectTo = '/post/list';
}

先程のLoginControllerとあまり変わりません。$redirectToには/post/listを指定しておきましょう。このPostRegisterControllerはユーザーの登録処理を行うコントローラーです。登録処理完了後のリダイレクト先$redirectToに指定します。

PostControllerの編集

ログインやログアウトなどの認証処理自体の部分は完成しました。実際にログイン済みでないと入れないページを作るために、PostControllerを編集していきます。

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Post;

class PostController extends Controller {

    /**
     * コンストラクタ
     */
    public function __construct() {
        // 認証ミドルウエアを利用する設定
        $this->middleware('auth');
    }

	// 他のメソッドは省略…
	// ....

}

上記のようにコントローラーにコンストラクタを作成します。

コンストラクタ内に$this->middleware('auth')と書くことで、このPostController内のその他のメソッドを実行する前に、ログイン済みかどうかをチェックしてくれます

ログイン済みでなければ、ログインページへ自動的にリダイレクトされます。

ビューファイルの編集

後はビューファイルです。今回作成した2つのコントローラでは、認証関連のコントローラーを継承したままの状態なので、デフォルトのビューファイルが利用されます。つまり、resources/views/auth/配下にあるビューファイルが利用されることになります。

この中にある各種ビューファイルを編集すればデザインは変更可能です。今回はビューファイルのデザイン修正に関しては本記事では省略します。

最後に既存で作成済みの記事リストのページのビューを少し編集していきましょう。

作成済みの記事リストのページも、PostControllerの編集によって、ログイン済みでなければアクセスできなくなりました。ログイン済みのページにログアウトのリンクがないのも変なので、ログアウトのリンクだけビューに作成しておきましょう。

記事リストのビューに以下のようなフォームを定義しておきます。

<form id="logout-form" action="{{ route('logout') }}" method="POST">
    @csrf
    <input type="submit" value="ログアウト">
</form>

これでログアウトのボタンが完成します。

ログアウトはただのリンクではなく、HTTP POSTメソッドで送信してあげます。ルーティングにもPOSTメソッドで定義されているはずです。

action属性の値として{{ route('logout') }}と書いてありますが、これはルーティングで設定したURLの名前です。

ログアウトはルーティングでRoute::post('logout', 'Auth\PostLoginController@logout')->name('logout');と設定していました。

->name('logout')がルーティングに名前を設定している部分です。
名前を設定しておくと、route('logout')とすることで、URLを文字列で取得することができますroute関数はLaravel内でグローバルに定義してあるヘルパ関数です。

最後に確認

これで以下の機能へ改修することができました。

ログイン・ログアウトや、ログイン済みでないとアクセスできないページ(記事リストや記事追加ページ等)にログインしていない状態でアクセスしてみてください。

認証機能が動作していることが確認できるかと思います。

まとめ

認証機能を改修していきました。これで管理者しかアクセスさせたくないページなどにログイン済みか確認する機能ができるようになりました。

さらに認証機能に変更を加えたい場合には、先程の継承したコントローラーなどに変更を加えれば、元のコントローラー(LoginControllerなど)には影響を出さずに改修することが可能になります。

また、その他認証についての細かい変更についてはLaravelのドキュメントを読みましょう。ややこしい認証の機能(マルチ認証など)については改めて記事にします。