Laravel5.5でメール認証登録できるようにする

Laravel5.5でメール認証登録できるようにする

  1. Laravelのデフォルトの認証機能を作成する
  2. Laravel5.5でメール認証登録できるようにする
    1. 認証テーブルをカスタマイズ
    2. 認証テーブルを作成する
    3. 認証機能を新しいテーブルに紐付ける

Laravelのデフォルトの認証機能を作成する

Laravel5でユーザー認証の設定
デフォルトの機能はartisanコマンド一発で作成さきます。

php artisan migrate
php artisan make:auth

デフォルトのDBテーブルを使って簡単な認証機能を実装できます。
ですが、これだといわゆる一般的なものではなく実在しないメールアドレスなどでも登録できてしいます。

Laravel5.5でメール認証登録できるようにする

通常の会員ページというのは最低限どれぐらいの機能実装が必要なのかというと、概ねこんな感じになるのではないかと思います。

  • 新規登録(仮登録)
  • 届いたメールでメールアドレスの認証(本登録)
  • ログイン
  • 動的::会員ページ (関連事項(詳細情報)の登録・編集・削除)
  • 静的::会員ページ (会員のための情報提供)
  • パスワードの再発行(パスワードを忘れた)
  • 退会
  • スーパーユーザー (会員のメールアドレスと決まったパスワードでログインすることができる)
  • 会員の等級(権限設定)

認証テーブルをカスタマイズ

デフォルトの認証テーブルは、usersテーブルとしてmigrateで作成されています。項目が非常にシンプルなのでもう少し必要な項目(カラム)を追加してカスタマイズします。

Column name
id
name
password
email
uniqueid newa add
uniquehash newa add
remember_token
description newa add
role newa add
status newa add
delflag newa add
created_at
updated_at

uniqueidは会員ID的なものを、uniquehashはメール認証で利用、descriptionは管理者のメモ、roleは権限、statusはアクティブユーザーなのかとか何らかの理由で権限が停止されているとかのフラグ、delflagは退会の理論削除、となります。
参考: 認証用のusersテーブルを変更する

認証テーブルを作成する

ここでは、base_usersテーブルを作成することにします。

php artisan make:model BaseUser --migration

database/migrations/yyyy_mm_dd_hhmmss_create_base_users_table.phpが作成され、同時にモデルファイルapp/BaseUser.phpも作成されます。
このマイグレーションファイルに作成したいカラムを追記します。既存の機能は踏襲したいので、以下のように設定します。

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateBaseUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('base_users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name', 128)->nullable();
            $table->string('password', 256)->nullable();
            $table->string('email')->nullable();
            $table->string('uniqueid', 64)->nullable();
            $table->string('uniquehash', 64)->nullable();
            $table->rememberToken()->nullable();
            $table->longText('description')->nullable();
            $table->integer('role')->nullable();
            $table->integer('status')->nullable();
            $table->unsignedTinyInteger('delflag')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('base_users');
    }
}

これでマイグレーションを行うと新しいDBテーブルが作成されます。
※ここでは一度ロールバックしてからマイグレーションになります。

php artisan migrate:rollback
php artisan migrate

これで新しい認証テーブルが作成されます。

認証機能を新しいテーブルに紐付ける

modelの根っこから改造する方法もあるんですが、ここでは既存のテーブルから新しく作成したテーブルに乗り換えるというようなかたちのカスタマイズをします。既存の認証テーブルのモデルファイルを修正して新しく作成したテーブルに向き先を変えてあげます。
まずはテーブル名を明示的に追記します。

// app/User.php
....(省略)
class User extends Authenticatable
{
/**
 * モデルと関連しているテーブル
 * @var string
 */
protected $table = 'base_users';
....(省略)
}

classの中に$tableプロパティーを追加することで認証テーブルの向き先が新しく作成したbase_usersテーブルに切り替わります。

続いて、$fillable/$guardedの設定を行います。アプリケーションの作りに依存するので、ここでは何を設定すべきなのかははっきりと言えないのですが、fillableは複数カラムを同時に変更できる値(カラム名)、$guardedはそれを行わせたくない値(カラム名)を設定します。
例えばuniqueidを永続的にユーザーをアイデンティファイする値と定義すると、この値は変更を加えたくない値です。idもオートインクリメントで自動で付番されているので、変更したくない値です。ユーザー名を変更したと同時にidを変更するということはシステム上あり得ないことになります。これらの塩梅はもちろんコントローラーまたはそれに準ずる機能で注意深く担保することもできるので、ここで考え込む必要もないのですが、ざっくり設定しておいた方がよいです。
暫定で、

    protected $fillable = [
        'name',
        'password',
        'email',
        'uniqueid',
        'uniquehash',
        'description',
        'role',
        'status',
        'delflag',
    ];

の設定をしておきます。

次に$hiddenの値を修正します。
モデルから変換する配列やJSONに、パスワードのような属性を含めたくない場合があります。それにはモデルの$hiddenプロパティに定義を追加してください。
これもfillableと同様に機能に依存する設定ですが、ざっくりと、

    protected $hidden = [
        'password', 'remember_token', 'uniquehash',
    ];

と、設定しておきます。
ここまでで、認証テーブルの変更が完了しました。

登録のフローをカスタマイズする

デフォルトの登録の機能は、/registerにアクセスし、必要事項を登録するだけで登録が完了します。これを、

  1. /registerにアクセスし、必要事項を入力
  2. 確認画面
  3. 登録したメールアドレスにメール送信(メール認証)
  4. メール内のURLをクリックして認証完了

にカスタマイズします。
あと、ここでは特に割愛しますがGUIは日本語化しておきましょう。

認証関連のルーティングとコントローラ

ルーティングとコントローラはこんな感じで設定します。

URI Controller
/register Auth\RegisterController@showRegistrationForm
/regist_confirm Auth\RegisterController@registConfirm
/regist_store Auth\RegisterController@registStore
/regist_mail_authenticate_user/{accesshash} Auth\RegisterController@mailAuthenticate

新規登録の概要

これらの機能は元々のフレームワークの機能として実装されているので、
app/Http/Controllers/Auth/RegisterController.phpは、

use Illuminate\Foundation\Auth\RegistersUsers

でもって、登録機能のすべてをここから継承しています。なので、実際にソースを確認するのは、vendor/laravel/framework/src/Illuminate/Foundation/Auth/RegistersUsers.phpということになります。このファイルは更にいろいろなパーツを別のclassやtraitから呼び出している構造になっています。
Laravelの基本的な機能(フレームワークの基本的な機能)としてこれらの基底Classをフロントコントローラにてオーバーライドできるようになっているので、これらの基底classは読むだけにして、実装自体はフロントコントローラで行います。

実装する

普通にルーティング、コントローラ、ビューを作成します。/registerにアクセスした際にはデフォルトのものがあるのでそれを使うのがよいでしょう。
routes/web.phpに以下追加。

....
Route::match(['get', 'post'],'/regist_confirm', 'Auth\RegisterController@registConfirm');
Route::post('/regist_store', 'Auth\RegisterController@registStore');
Route::get('/regist_mail_authenticate_user/{accesshash}', 'Auth\RegisterController@mailAuthenticate');
....

app/Http/Controllers/Auth/RegisterController.phpに諸々追加してゆきます。
ここはやたらと修正箇所があるので、修正ファイルをそのまま見てみてください。
(後ほどソース載せます。)

ログインの条件の変更

新規登録でメール認証前のデータ登録(インサート)はstatusを1にして登録しています。このフラグを仮登録としています。メールが送信され指定のURLを踏むと本登録となる際にstatusを2にします。となると、ログインの条件が変更になるわけです。
デフォルトではEmailアドレスとパスワードでログインができます。カスタマイズ後は、Emailアドレスとパスワードに加えて、statusが2であることを条件にします。
この条件は、Illuminate\Foundation\Auth\AuthenticatesUsers(vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php)のcredentials()メソッドを修正します。例によってvendor以下のライブラリを触るのはご法度なので、app/Http/Controllers/Auth/LoginController.phpにAuthenticatesUsersトレイトを継承してオーバーライドします。

送信メールの設定

デフォルトで設定してくれてないのでひと手間必要です。Larabelのメール送信はbladeのテンプレートを使って送信するのがベストです。(HTMLメールのみでプレーンテキストのメール送信ができないというのが難点ですが、それでもbladeを使った方がいいです。)
Laravel5で送信メールサーバー設定

Last update: 2018.04.10 (火)