たった3ステップ!Laravelで仮登録→本登録を実装する方法

さてさて、前回のシンプル!Laravel5.6で「権限つき」ログインさせる方法でも書きましたが、Laravelには始めから色々な機能が備わっていて便利ですが、中には自分で実装する必要がある部分もあります。

それが今回の「仮登録→本登録」機能の実装です。

流れとしては、

  1. ユーザー登録(仮登録)
  2. 本登録URLをメール送信
  3. クリックされたら本登録完了

というものです。

完全に自前で実装するとなるとなかなか大変なのですが、そこは人気フレームワークのLaravel。便利なパッケージが公開されているので、それを使ってたった3ステップで実装することができます。

では、やってみましょう!

【開発環境】

  • Laravel 5.6.15
  • PHP 7.2
  • Apache 2.4
  • Ubuntu 16.04

※すでにphp artisan make:authで、デフォルトの認証機能が追加されている前提です。

1.インストール

利用するパッケージ名は、「laravel-user-verification」です。
composerからコマンド一発でインストールできます。

composer require jrean/laravel-user-verification:dev-master

そして、パッケージのマイグレーションを実行します。

php artisan migrate --path="/vendor/jrean/laravel-user-verification/src/resources/migrations"

この実行で、usersテーブルに以下のフィールドが追加されることになります。

  • verified
  • verification_token

2.準備

app/Http/Controllers/Auth/RegisterController.phpの中で、以下3つを行います。

  • VerifiesUsersを読み込み
  • コンストラクタの中身を変更
  • register()をオーバーライド
<?php

namespace App\Http\Controllers\Auth;

use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Auth\Events\Registered;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
use Jrean\UserVerification\Traits\VerifiesUsers;
use Jrean\UserVerification\Facades\UserVerification;

class RegisterController extends Controller
{
    /* 省略 */

    use VerifiesUsers;

    /* 省略 */

    public function __construct()
    {
        $this->middleware('guest', ['except' => ['getVerification', 'getVerificationError']]);
    }

    /* 省略 */

    public function register(Request $request)
    {
        $this->validator($request->all())->validate();

        $user = $this->create($request->all());

        event(new Registered($user));

     $this->guard()->login($user);

        UserVerification::generate($user);

        UserVerification::send($user, '仮登録が完了しました');

        return $this->registered($request, $user)
            ?: redirect($this->redirectPath());
    }
}

※use *****でパッケージのネームスペースを忘れないようにしてください。
元々はトレイト内で設定されているので、オーバーライドすると呼び出せなくなってしまいます。

※コンストラクタでは、本登録ページでミドルウェアが適用されないようにしています。適用されると、ログイン済みということで自動リダイレクトされてしまうからです。

そして、まだ本登録されていない場合は例外を出すようにミドルウェアを登録しましょう。

app/Http/Kernel.php

protected $routeMiddleware = [
    /*  省略  */
    'isVerified' => \Jrean\UserVerification\Middleware\IsVerified::class,
];

これで、「isVerified」ミドルウェアを読み込んでいるページは本登録されていないとエラー(例外)が発生するようになります。

3.見た目を変更する(任意)

デフォルトだと、本登録メールは英語になっていたりするので、これを変更しておきましょう。(もし必要ない人は次の項目まで読み飛ばして下さい)

変更するのは以下の3つです。

  • 本登録メールの日本語化
  • 本登録・失敗ページの日本語化
  • 本登録がまだできていない場合のエラーページ

本登録メールの日本語化

まずは本登録メールの内容です。
次のコマンドでビューをpublishします。

php artisan vendor:publish --provider="Jrean\UserVerification\UserVerificationServiceProvider" --tag="views"

実行が完了すると、

resources/views/vendor/laravel-user-verification

の中に3つのビューが作成されます。

メール内容を変更するには、「email.blade.php」の中身を以下のように変更して保存して下さい。

以下のURLから本登録を完了させてください。

本登録URL: <a href="{{ $link = route('email-verification.check', $user->verification_token) . '?email=' . urlencode($user->email) }}">{{ $link }}</a>

本登録・失敗ページの日本語化

次に本登録がなんらかの理由で失敗した場合、

http://l56.test/email-verification/error

にリダイレクトされるのですが、このページもさっきpublishしたビューでカスタマイズできます。

user-verification.blade.php

@extends('layouts.app')

<!-- Main Content -->
@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <h1>本登録・認証エラー</h1>
            <div class="panel-body">
                <span class="help-block">
                    <strong>本登録の認証に失敗しました。URLが途中で途切れている場合があります。もう一度お確かめの上、アクセスしてください。</strong>
                </span>
                <br>
                <br>
                <a href="{{url('/')}}" class="btn btn-primary">
                    トップページへ戻る
                </a>
            </div>
        </div>
    </div>
</div>
@endsection

※元々はtrans()を使って多言語化に対応させていますが、今回はサンプルということで直接文章をかき込んでいます。

本登録がまだできていない場合のエラーページ

最後に、本登録していないのに該当ページへアクセスしたら表示するエラーページを作成します。(ミドルウェア「\Jrean\UserVerification\Middleware\IsVerified」で発生したエラーです)

まず、以下のようにエラービューを作成します。

(resources/views/errors/not_verified.blade.php)

@extends('layouts.app')

<!-- Main Content -->
@section('content')
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <h1>本登録が完了していません。</h1>
            </div>
        </div>
    </div>
@endsection

そして、エラーページを表示するHandler.php内で呼び出すコードを追加します。

app/Exceptions/Handler.php

<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Jrean\UserVerification\Exceptions\UserNotVerifiedException;

class Handler extends ExceptionHandler
{
    /* 省略 */
    public function render($request, Exception $exception)
    {
        if ($exception instanceof UserNotVerifiedException) {

            return response()->view('errors.not_verified', [], 500);

        }

        return parent::render($request, $exception);
    }
}

これで、完了です。

実際に確かめてみる

では、Routeに本登録が完了したユーザーだけが見られるページを登録してアクセスしてみましょう。

Route::group(['middleware' => ['auth', 'isVerified']], function () {

    Route::get('/user/home', function(){

        return 'ログインもできてるし、本登録も完了してます!';

    });

});

ミドルウェアとして、

  • auth ・・・ 通常のログイン
  • isVerified ・・・ 本登録が完了してるかどうかをチェックするミドルウェア

の2つが登録されていることに注意して下さい。

そして、ログインした状態で以下のページにアクセスしてみると、「本登録がまだできていない場合のエラーページ」で作成したページが表示されると思います。

http://example.com/user/home

もちろん、本登録を済ませてある場合はエラーページは表示されず、この場合だと「ログインもできてるし、本登録も完了してます!」と表示されます。

ということで、今回はLaravelで「仮登録→本登録」を実装する方法を紹介しました。
お役に立てたら幸いです。

ではでは〜。