Laravel JetstreamのEmail Verification(認証メール)の使い方

こんにちは。フリーランス・コンサルタント&エンジニアの 九保すこひ です。

さてさて、ここのところLaravel 8.xの目玉機能「Jetstream」の記事をお届けしています。

そして今回は、「Laravel Jetstream の各種フォームを日本語化する」の「おわりに」で触れた話題です。

それは・・・・・・・

Email Verification(認証メール)

です。

これは、誰でも登録できるタイプのウェブサービスの場合に問題になる「登録されたメールアドレスが本当に正しいのか??」という問題を解決するための機能です。

つまり、実際に登録されたメールアドレスに「認証メール」を送り、そこに書かれているリンクをクリックしてもらうことで正しいメールアドレスかどうかをチェックするわけです。

※これをやっておかないと、もしパスワードがわからなくなった場合、パスワード再発行ページで登録したメールアドレスを送信しても間違ったところに届くので、二度と自分では復活できなくなってしまいます。

そこで❗

今回はこのEmail Verificationを使う方法と、前回に引き続き日本語化する方法もご紹介します。

ぜひ皆さんのお役に立てましたら嬉しいです😊✨
(最後に、日本語化用のソースコード一式をダウンロードできますよ👍)

「メールアドレスが間違っていると、
運営側からしてもめんどうです😭」

開発環境: Laravel 8.x

前提として

もちろんLaravel Jetstreamがインストールされていることが前提です。
もしまだの方は以下のページを参考にしてみてください。

📝 Laravel8.x以降でログイン機能をインストールする方法

Email Verificationを有効にする

では、Email Verificationを使えるようにしていきましょう。

まず、コンフィグファイルの変更です。

config/fortify.php

<?php

use App\Providers\RouteServiceProvider;
use Laravel\Fortify\Features;

return [

    // 省略

    'features' => [
        Features::registration(),
        Features::resetPasswords(),
        Features::emailVerification(), // 👈 ここのコメントアウトを除去
        Features::updateProfileInformation(),
        Features::updatePasswords(),
        Features::twoFactorAuthentication(),
    ],

];

そして、Userモデルの中身も変更します。

<?php

namespace App\Models;

use App\Events\UserCreated;
use Illuminate\Contracts\Auth\MustVerifyEmail; // 👈 ここを追加しました
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Fortify\TwoFactorAuthenticatable;
use Laravel\Jetstream\HasProfilePhoto;
use Laravel\Jetstream\HasTeams;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable implements MustVerifyEmail // 👈 ここを追加しました
{
    // 省略

これでEmail Verification自体は有効になりました!

日本語化する

ここまでの作業だけでEmail Verification自体は有効になっているため、ユーザー登録しようとすると自動的に認証メールが送信されることになります。

ただし、フォームや送信される認証メールは全て英語で書かれているため、ここからは日本語化の方法をご紹介します。

ビューを日本語化する

まず、ユーザー登録した時に表示されるテキストを日本語化します。(太字が変更した部分です)

resources/views/auth/verify-email.blade.php

<x-guest-layout>
    <x-jet-authentication-card>
        <x-slot name="logo">
            <x-jet-authentication-card-logo />
        </x-slot>

        <div class="mb-4 text-sm text-gray-600">
            ご登録ありがとうございます!<br>
            ご入力いただいたメールアドレスへ認証リンクを送信しましたので、クリックして認証を完了させてください。<br>
            もし、認証メールが届かない場合は再送させていただきます。
        </div>

        @if (session('status') == 'verification-link-sent')
            <div class="mb-4 font-medium text-sm text-green-600">
                新しい認証メールが送信されました。
            </div>
        @endif

        <div class="mt-4 flex items-center justify-between">
            <form method="POST" action="/email/verification-notification">
                @csrf

                <div>
                    <x-jet-button type="submit">
                        認証メールを再送する
                    </x-jet-button>
                </div>
            </form>

            <form method="POST" action="/logout">
                @csrf

                <button type="submit" class="underline text-sm text-gray-600 hover:text-gray-900">
                    ログアウト
                </button>
            </form>
        </div>
    </x-jet-authentication-card>
</x-guest-layout>

認証メールを日本語化する

認証メールを日本語化するには、専用のNotificationをつくって実装します。

以下のコマンドを実行してください。

php artisan make:notification VerifyEmailJapanese

すると、ファイルが作成されるので中身を次のように変更してください。

app/Notifications/VerifyEmailJapanese.php

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\URL;

class VerifyEmailJapanese extends Notification
{
    /**
     * The callback that should be used to build the mail message.
     *
     * @var \Closure|null
     */
    public static $toMailCallback;

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

    /**
     * Build the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        $verificationUrl = $this->verificationUrl($notifiable);

        if (static::$toMailCallback) {
            return call_user_func(static::$toMailCallback, $notifiable, $verificationUrl);
        }

        return (new MailMessage)
            ->subject(Lang::get('メールアドレスを認証してください'))
            ->line(Lang::get('以下のボタンをクリックしてメールアドレスを認証してください'))
            ->action(Lang::get('認証する'), $verificationUrl)
            ->line(Lang::get('(もしこのメールに覚えがない場合は放置して問題ございません)'));
    }

    /**
     * Get the verification URL for the given notifiable.
     *
     * @param  mixed  $notifiable
     * @return string
     */
    protected function verificationUrl($notifiable)
    {
        return URL::temporarySignedRoute(
            'verification.verify',
            Carbon::now()->addMinutes(Config::get('auth.verification.expire', 60)),
            [
                'id' => $notifiable->getKey(),
                'hash' => sha1($notifiable->getEmailForVerification()),
            ]
        );
    }

    /**
     * Set a callback that should be used when building the notification mail message.
     *
     * @param  \Closure  $callback
     * @return void
     */
    public static function toMailUsing($callback)
    {
        static::$toMailCallback = $callback;
    }
}

Notificationを作成したら、次はUserモデルに登録します。

app/Models/User.php

// 省略

class User extends Authenticatable implements MustVerifyEmail
{
    // 省略

    // 👇 ここを追加しました
    public function sendEmailVerificationNotification()
    {
        $this->notify(new \App\Notifications\VerifyEmailJapanese);
    }
}

ただし、実はこれだけで以下のように中途半端な日本語化になります。

これはEmail Verificationの問題ではなく、Notification本体での設定になります。

では、パッケージからこの部分のビューをLaravel本体へコピーして日本語化していきましょう。

以下のコマンドを実行してください。

php artisan vendor:publish

すると、コピーできるリストが表示されますので、「laravel-notifications」と書かれている番号を入力してEnterキーを押してください(番号は環境によって違うと思います)

これで、ファイルのコピーが完了したので実際に日本語化していきましょう。(太字が変更した部分です)

resources/views/vendor/notifications/email.blade.php

@component('mail::message')
{{-- Greeting --}}
@if (! empty($greeting))
# {{ $greeting }}
@else
@if ($level === 'error')
# @lang('エラー発生')
@else
# @lang('こんにちは!')
@endif
@endif

{{-- Intro Lines --}}
@foreach ($introLines as $line)
{{ $line }}

@endforeach

{{-- Action Button --}}
@isset($actionText)
<?php
    switch ($level) {
        case 'success':
        case 'error':
            $color = $level;
            break;
        default:
            $color = 'primary';
    }
?>
@component('mail::button', ['url' => $actionUrl, 'color' => $color])
{{ $actionText }}
@endcomponent
@endisset

{{-- Outro Lines --}}
@foreach ($outroLines as $line)
{{ $line }}

@endforeach

{{-- Salutation --}}
@if (! empty($salutation))
{{ $salutation }}
@else
ご利用ありがとうございました!<br>
{{ config('app.name') }}
@endif

{{-- Subcopy --}}
@isset($actionText)
@slot('subcopy')
@lang(
    "もし「:actionText」ボタンをクリックしてもうまく移動できない場合は、以下のURLを直接ブラウザにコピー&ペーストしてください。\n",
    [
        'actionText' => $actionText,
    ]
) <span class="break-all">[{{ $displayableActionUrl }}]({{ $actionUrl }})</span>
@endslot
@endisset
@endcomponent

これで設定は完了です!

テストしてみる

では、実際にユーザー登録してEmail Verificationが日本語化されているか確認してみましょう❗

まずは、「http://******/register」にアクセスして、ユーザー登録します。

これまでならこれで、自動ログインして終了でしたが、今回は以下の表示になりました。

うまくいきました😊

では、認証メールがどうなっているかも確認してみましょう。

こちらもうまくいきました!

では、最後に「認証する」ボタンをクリックしてusersテーブルのemail_verified_atにデータが書き込まれるかをチェックします。

クリックすると・・・・・・

はい❗
日時が書き込まれて認証が完了しました。

今後は以下のようにすることでメール認証が完了しているかどうかチェックすることができます。

$user = \App\Models\User::find(1);

if($user->hasVerifiedEmail()) {

    echo '認証済みです';

} else {

    echo 'まだ認証されていません';

}

お疲れ様でした😊✨

ちなみに: Cannot send message without a sender address というエラーが出たら

.envMAIL_FROM_ADDRESSが設定されていないことが原因です。
以下のように設定しておきましょう。(もちろん好きなメールアドレスでOKです👍)

MAIL_FROM_ADDRESS=info@example.com

ダウンロードする

今回実際に開発したソースコード一式を以下からダウンロードできます。

Laravel JetstreamのEmail Verification(認証メール)の使い方

※ただし、メールの設定などはご自身で実装していただく必要があります。

開発のご依頼お待ちしております
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします! by 九保すこひ

おわりに

ということで、今回はLaravel JetstreamEmail Verificationを使う方法をご紹介しました。

日本語化には少しやることが多いですが、Notificationもからんでいますので、勉強になることは多いんじゃないでしょうか。

ぜひ今回の記事で別の部分もブラッシュアップしてみてくださいね。

ではでは〜❗

「独自のパッケージを
作らなくなっちゃったな・・・
管理が大変ですよね😂」

このエントリーをはてなブックマークに追加       follow us in feedly