Fippiyのプログラム学習内容アウトプットBlog

日々の学習内容をアウトプットして振り返りを実施する。

Laravel開発、Auth機能を拡充する【3】新規登録時のメールアドレス確認を実装する

前回の記事でAuth機能のメールを利用してパスワードリセット…までを実装しました。

メールを利用した機能として新規登録時のユーザー認証があるので、今回はこちらを実装していきます。

前回の記事はこちら

fippiy.hatenablog.jp

 

今回の目的

新規登録時に登録アドレス宛にメールを送付し本人認証を行う

なぜやるか

  • Auth機能の未実装ファイルを使えるようにしておく
  • 有効なアドレスで利用されていることを確認するため

やりたいこと

  • 新規登録時のメールアドレスで認証したい
  • 認証済みユーザーのみがログインできるようにしたい
  • Userテーブルの未使用カラムの使い道を確認したい

やったこと

  • 新規登録時認証の実装方法を確認する
  • 認証メールを送付できるようにする
  • 認証確認済みユーザーのみログインできるようにする
  • Userテーブル未使用カラムの状態を確認する
  • メール送付完了時のメッセージを日本語化する
  • メールの文章を日本語化する
  • 本番環境での設定を行う
  • 認証完了前に別ユーザーに切り替える

実施内容

メール認証を実装する

新規登録時のメール認証実装手順を確認する

まずはどう実装すればいいか確認しました。

こちらを参考にさせて頂きました、ありがとうございます。

qiita.com

これを実装します。

 

設定変更して実装する

ユーザーモデルを編集して新規登録時のメール送付機能に対応します。

# ~/app/User.php

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail as MustVerifyEmailContract;
use Illuminate\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Facades\Auth;
use App\Notifications\CustomResetPassword;

class User extends Authenticatable implements MustVerifyEmailContract
{
use MustVerifyEmail, Notifiable;

 

ルート設定でverifyを有効にします。

# ~/routes/web.php

// ログインルート
Auth::routes(['verify' => true]);

この2つの設定でメール送付が有効になるようです。

※その他にメール送信設定が必要です。前々回の記事にてメール送信機能は設定済みです。

 

まずは、この状態で新規登録を実施。

f:id:Fippiy:20190419134257p:plain

新規登録メール

メールが届きました。

しかし、まだこれでは問題点があります。

  1. メールは送信されているがログインがすでに完了している。
  2. メールのVerify Email Addressをクリックしても接続できない。

メールが届くという機能が追加されただけで、認証とはほど遠い物となっています…。

 

DBカラムを確認する

この時点でずっと気になっていたUserテーブルの使用していないカラムを確認してみました。

パスワードリセットでカラムを使用していたので、認証機能で残りのカラムを使うと想定していました。

 

# メール送付機能実装後のDB

f:id:Fippiy:20190419134510p:plain

DB確認

email_verified_atに日時が記録されました、新規登録時の動作としてこちらのカラムを使用しているんですね。

詳しい動作はまだ分かっていませんが、まずこのカラムが使われているということが確認できました。

 

認証後にログインできるようにする 

メール送付はされるもののログインできてしまっている…に対応します。

ミドルウェア設定を変更します。

f:id:Fippiy:20190419135107p:plain

ミドルウェア設定変更

middleware=>authをverifiedに変更しました。

auth設定はログイン済みか判定し、ログインしていなければリダイレクトするものです。

verifiedに変更することで、認証完了ユーザであればアクセス可能という設定になっています。

この状態で再度新規登録を試します。

# 新規登録後ビュー

f:id:Fippiy:20190419135133p:plain

新規登録後

 

この状態で実際に新規登録すると、メール確認のメッセージが出力されました。

 

認証メールから登録を完了させる

メール内のVerifi Email Addressをクリックすると認証が完了する…という流れです。

しかし、クリックすると~/homeにアクセスしました。

どこかでリダイレクト設定がはいっているようです、パスワードリセットを実装しているときにもこんなことがありました。

そして~/homeはすでに削除しているページなのでアクセスできません。

verifiのコントロールを確認しました。

# ~/app/Http/Controllers/Auth/VerificationController.php

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\VerifiesEmails;

class VerificationController extends Controller
{
/*
|--------------------------------------------------------------------------
| Email Verification Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling email verification for any
| user that recently registered with the application. Emails may also
| be re-sent if the user didn't receive the original email message.
|
*/

use VerifiesEmails;

/**
* Where to redirect users after verification.
*
* @var string
*/
protected $redirectTo = '/home';

リダイレクト先が/homeになっていました。修正します。

# ~/app/Http/Controllers/Auth/VerificationController.php

protected $redirectTo = '/book';

そして、再度メールからアクセス。

# 認証後ビュー

f:id:Fippiy:20190419141300p:plain

web表示

認証が完了し、ログインできました。

 

認証時の動作を確認する

再度、新規登録する

ここで、詳しく新規登録からログインするまでの動作を確認します。

まずは新規登録を実施。

f:id:Fippiy:20190419135133p:plain

登録確認画面

メールを確認する旨のメッセージがでます。

認証前のDB状態を確認

f:id:Fippiy:20190419141556p:plain

DBレコード

今回のユーザーはid=20です。メール送信時点でユーザー情報は登録されています。

が、email_verified_atには何も登録されていません。

最終的にemail_verified_atにはデータが登録されることを先程確認しています。

 

メール認証せずにログイン

次に、メール確認…をせずに、一度トップページに戻り、ログインのボタンを押してみました。

f:id:Fippiy:20190419135133p:plain

メール確認画面

何も入力していないにもかかわらず、メールを確認する画面がいきなり表示されました。

 

どうやら、従来のログイン処理と同様に、ログイン済みであればログインフォームは表示されずにログイン後のページにリダイレクトされるようです。このアプリでは~/bookにリダイレクトされます。しかしメール認証が終わっていない為、認証してくださいメッセージが表示されているようです。

 

メール認証してDB状態を確認

そして、メールから認証を行います。

f:id:Fippiy:20190419134257p:plain

認証を実施

認証完了すると、webページ内部にアクセスできます。

 

そして、その後のDBを確認します。

f:id:Fippiy:20190419142145p:plain

認証後のDB

email_verified_atにデータが記録されました、これで認証が完了しているのでログインができるという流れのようです。

 

DB登録済みユーザーでログインしてみる

DBには仮のメールアドレスで何度も登録を実験したユーザーが存在しています。

今まではメール認証がなかったので、登録さえすればログインできる状態でした。

このユーザーでログインをためすと、メール認証されていない状態(email_verified_atがnull)なので、メール認証メッセージが表示されました。

メール認証設定後はemail_verified_atの値によって認証完了済みか確認しているようです。
 

フォームデザインをなおす

新規登録後メール送付のメッセージが表示されますが、ビューファイルを修正します。 

現状のビューファイルはこちら。

# ~/resources/views/auth/verify.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Verify Your Email Address') }}</div>

<div class="card-body">
@if (session('resent'))
<div class="alert alert-success" role="alert">
{{ __('A fresh verification link has been sent to your email address.') }}
</div>
@endif

{{ __('Before proceeding, please check your email for a verification link.') }}
{{ __('If you did not receive the email') }}, <a href="
{{ route('verification.resend') }}">{{ __('click here to request another') }}</a>.
</div>
</div>
</div>
</div>
</div>
@endsection

Authコマンドで自動生成されたフォームです。

ログインやパスワードリセットページと同じデザインでフォーマットを再作成します。

併せて、英文を日本語に修正します。

@extends('layouts.app')

@section('content')
<div class="auth-contents">
<div class="auth-contents__message">
@if (session('resent'))
<div class="auth-contents__message--message" role="alert">メールを再送しました。</div>
@endif
<div class="auth-contents__message--message">新規登録を受け付けました。</div>
<div class="auth-contents__message--message">登録したメールアドレス宛にメールを送信しました、
メールを確認して登録を完了させて下さい。</div>
<div class="auth-contents__message--message">
メールが送付されていない場合
<a href="{{ route('verification.resend') }}">こちらをクリック</a>
することで、再送できます。
</div>
</div>
</div>
@endsection

直訳文章は変な感じだったので、適当に日本語らしくしてます。

# 登録後ビュー

f:id:Fippiy:20190419144347p:plain

送信完了メッセージ

これでフォーム側は修正できました。

最後の一文のクリックをすることで、メールが再度送付されるようになっています。

 

メールの文章を日本語化する

最後に、前回同様メールの文章を修正します。

前回テンプレート側については修正しているので、すでに日本語化されているところもあります。

本文が英語のままなので、修正していきます。

先程の参考サイトに手順があるのですが、前回のメール設定と実施する内容はほぼ同じ様です。

カスタム通知を作成して日本語化設定していきます。

カスタムファイルを作成

$ php artisan make:notification CustomVerifyEmail

カスタムファイルで日本語を設定

# ~/app/Notifications/CustomVerifyEmail.php

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Auth\Notifications\VerifyEmail;

class CustomVerifyEmail extends VerifyEmail
{
use Queueable;

/**
* Create a new notification instance.
*
* @return void
*/
public function __construct()
{
//
}

/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['mail'];
}

/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->subject('メールアドレス確認')
->line('下のボタンをクリックしてメールアドレスの確認を完了してください。')
->action('パスワード確認', $this->verificationUrl($notifiable))
->line('もし心当たりがない場合は、本メッセージは破棄してください。');
}

/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}

実際に新規登録してメール送付を受け取ります。

# メール

 

f:id:Fippiy:20190419151800p:plain

日本語化メール

以上でAuth機能として残っていたメールを利用した新規登録を実装しました。

 

 

本番環境で新規登録する

このまま後は本番環境で動作確認して完了…といいたいところでしたが、メールから認証するとエラー表示となりました。

対策を探していたところ、こちらを参考にさせて頂きました、ありがとうございます。

qiita.com

本番環境での認証にあわせた設定を追加で実装する必要が有りました。

TrustProxies.phpの設定変更をして再度認証し、認証が完了しました。

 

ユーザーを切り替える

メール認証前に別ユーザーに切り替えるには

※認証の流れでふれた内容から対策を考えました。

登録したものの、メールアドレスが実は誤っていたということもあります。

 

メールを送付した段階では認証未完了となるわけですが、内部的にはログインはしていて認証はまだ…という状態です。このため、認証前に再度新規登録しようとしてもログインはしているので、ログイン画面に遷移→認証は未完了→認証確認画面となります。

 

この為、別のメールアドレスで再度新規登録しよう…としても上記状態となり新規登録画面が表示されません。

 

ユーザーを切り替える

この状況を回避する為に、認証中状態となった時にユーザー切替ボタンを表示させることにしました。

切替…といって置きながら、実際に設置したのはログアウトボタンです。

本来ログアウトボタンはログイン後のページでのみ表示しているのですが、認証中のためアクセスはまだできません。

ですが、ログアウト処理をしてやることで、他のユーザーとして登録し直すことができるようになるので、この処理を加えることにしました。

 

# ログアウトボタンを設置したメール送付ページ

f:id:Fippiy:20190419161552p:plain

切替ボタン

これで、メールアドレスが間違っていたなど、登録先を変更したい場合も対応できるようになりました。

 

以上でAuth機能を使った設定が完了しました。

次はAuth以外にもユーザーに関する情報を扱う必要が有るので、そちらを設定していきます。