PHP
laravel

Laravel 5.5 の認証機能とそのカスタマイズ

Laravelの認証

Laravelにデフォルトで用意されている認証機能を使ってみました。
また、カスタマイズもやってみましたので、そのメモです。

参考リンク

クイックスタート

まず新しくlaravelプロジェクトを作成します。
Laravel Installerが入っているなら以下のようなコマンド一行で作成できます。

laravel new auth-test

次に適当な空のデータベースを作成し、.envファイルを適切に設定してください。ローカルならば以下の3つを設定すればだいたい動くと思います。

DB_DATABASE=データベース名
DB_USERNAME=データベースのユーザー名
DB_PASSWORD=データベースのパスワード

作成されたプロジェクトディレクトリの中で以下を実行します。

php artisan make:auth
php artisan migrate
php artisan serve

トップページ(例: http://localhost:8000/ )を開くと、右上に「LOGIN」「REGISTER」のメニューがあり、REGISTERを押してユーザー登録をするとトップページのメニューが「HOME」に変わります。

認証で使われるソースファイル

make:authコマンドにより、以下のルートとビューが一括で作成されます。
コントローラー・モデル・マイグレーションファイルは最初から用意されています。

追加されたルート

routes/web.phpに以下の一文が追加されます。

Auth::routes();

これはAuthファサードを通してIlluminate\Routing\Routerインスタンスのauthメソッドを呼び出しています。これにより以下のルートが追加されます。

// 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...
$this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
$this->post('register', 'Auth\RegisterController@register');

// Password Reset Routes...
$this->get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
$this->post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
$this->get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
$this->post('password/reset', 'Auth\ResetPasswordController@reset');

上から、ログイン用・ユーザー登録用・パスワードリセット用のルートです。

追加されたビュー

make:authコマンドによりresources/views/authディレクトリにいくつかビューファイルが追加されます。

  • login.blade.php ログイン用のフォーム
  • register.blade.php ユーザー登録用のフォーム
  • passwords/email.blade.php パスワードリセット用のメール送信フォーム
  • passwords/reset.blade.php パスワードリセット用の新パスワード登録フォーム

resources/views/layouts/app.blade.phpに共通レイアウトも追加されます。

コントローラー

app/Http/Controllers/Authディレクトリに認証用のコントローラーが最初から用意されています。

  • LoginController.php ログインフォーム・ログイン・ログアウト
  • RegisterController.php ユーザー登録フォーム・ユーザー登録
  • ForgotPasswordController.php パスワードリセット用のメール送信フォーム・パスワードリセット用のメール送信
  • ResetPasswordController.php パスワードリセット用の新パスワード登録フォーム・パスワードリセット用の新パスワード登録

マイグレーション

database/migrationsディレクトリに最初から用意されています。

***_create_users_table.phpがユーザーテーブル、
***_create_password_resets_table.phpがパスワードリセット用のテーブルです。

モデル

こちらも最初からapp/User.phpに用意されています。

カスタマイズ

ログイン後のリダイレクト先の変更

ログインすると/homeへリダイレクトされますが、これをカスタマイズするには、LoginControllerRegisterControllerResetPasswordControllerredirectToプロパティにリダイレクト先を定義します。

protected $redirectTo = '/';

ログイン対象のカラムの変更

デフォルトではemailカラムを認証に利用します。これを変更するには、テーブルに対象のカラムを追加し、ユーザー登録フォームとログインフォームをカスタマイズします。

例としてuseridカラムを認証に使う方法を以下に示します。

テーブルにログイン対象カラムを追加する

まず、マイグレーションファイルを作成します。

php artisan make:migration update_users_table --table=users

作成された***_update_users_table.phpupメソッドに以下を追加するとuseridカラムが追加されます。

$table->string('userid')->unique()->after('email');

downメソッドも定義しておきましょう。

$table->dropColumn('userid');

マイグレーションします。

php artisan migrate

ユーザー登録フォームをカスタマイズする

次に、ユーザー登録フォームに入力欄を追加してみます。

resources/views/auth/register.blade.phpname欄をコピーして属性等をuseridに変更して欄を増やします。

<div class="form-group{{ $errors->has('userid') ? ' has-error' : '' }}">
    <label for="userid" class="col-md-4 control-label">User ID</label>

    <div class="col-md-6">
        <input id="userid" type="text" class="form-control" name="userid" value="{{ old('userid') }}" required>

        @if ($errors->has('userid'))
            <span class="help-block">
                <strong>{{ $errors->first('userid') }}</strong>
            </span>
        @endif
    </div>
</div>

さらに、レコードを登録する部分である、app/Http/Controllers/Auth/RegisterController.phpcreateメソッドにuseridを追加します。

protected function create(array $data)
{
    return User::create([
        'name' => $data['name'],
        'email' => $data['email'],
        'userid' => $data['userid'], // 追加
        'password' => bcrypt($data['password']),
    ]);
}

もうひとつ設定しなければいけない箇所があります。モデルのcreateメソッドは、フォームなどからの予期せぬ一括代入を防ぐために、$fillableプロパティで代入できる項目を制限しています。

よってapp/User.php$fillableプロパティにuseridを追加します。

protected $fillable = [
    'name', 'email', 'userid', 'password',
];

これで登録ができるようになります。値のバリデーションが必要ならapp/Http/Controllers/Auth/RegisterController.phpvalidatorメソッドに追加します。

ログインフォームをカスタマイズする

次に、ログインフォームをカスタマイズします。

resources/views/auth/login.blade.phpemail欄をuserid欄に変更します。

<div class="form-group{{ $errors->has('userid') ? ' has-error' : '' }}">
    <label for="userid" class="col-md-4 control-label">User ID</label>

    <div class="col-md-6">
        <input id="userid" type="text" class="form-control" name="userid" value="{{ old('userid') }}" required autofocus>

        @if ($errors->has('userid'))
            <span class="help-block">
                <strong>{{ $errors->first('userid') }}</strong>
            </span>
        @endif
    </div>
</div>

さらに、ログイン対象カラムを変更するために、app/Http/Controllers/Auth/LoginController.phpusernameメソッドを定義します。

public function username()
{
    return 'userid';
}

これでuseridpasswordでログインできるようになります。

Userモデル以外を認証に使う

例えばStaffモデルを使う場合はconfig/auth.phpを以下のように変更します。

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Staff::class,
        ],
    ],

StaffモデルはModelクラスではなくAuthenticatableクラスを継承する必要があります。
パスワードのカラムは最低60文字必要で、デフォルトの255文字が良いみたいです。
さらに自動ログインを使う場合はremember_tokenカラムも必要です。rememberTokenメソッドを使ってマイグレーションするのが良いでしょう。