
九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて、ここのところ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 というエラーが出たら
.env
のMAIL_FROM_ADDRESS
が設定されていないことが原因です。
以下のように設定しておきましょう。(もちろん好きなメールアドレスでOKです)
MAIL_FROM_ADDRESS=info@example.com
ダウンロードする
今回実際に開発したソースコード一式を以下からダウンロードできます。
Laravel JetstreamのEmail Verification(認証メール)の使い方※ただし、メールの設定などはご自身で実装していただく必要があります。
おわりに
ということで、今回はLaravel Jetstream
でEmail Verification
を使う方法をご紹介しました。
日本語化には少しやることが多いですが、Notification
もからんでいますので、勉強になることは多いんじゃないでしょうか。
ぜひ今回の記事で別の部分もブラッシュアップしてみてくださいね。
ではでは〜
「独自のパッケージを
作らなくなっちゃったな・・・
管理が大変ですよね」