13
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Laravel6.xでパスワードリセットメールをカスタマイズする

Last updated at Posted at 2019-12-18

やりたいこと

  • Laravelのauthで導入されるログイン機能は便利だけど、パスワードリセットやメール認証のメールが英語なので、日本語にしたい。
  • 言語ファイルいじるだけでも日本語化は出来るが、できれば好きなデザイン・内容にしたい。

環境

  • Laravel 6.x (執筆時点では6.5.2)
$ php artisan --version
Laravel Framework 6.5.2
  • 事前に認証機能の導入を済ませている。
    • 具体的に言うと下記コマンドを実行済みで、プロジェクトも作ってある。
$ composer require laravel/ui "^1.0" --dev
$ php artisan ui vue --auth

大雑把な流れ

  • Userクラスの通知関数をオーバーライド
  • そこで用いるためのNotificationを作成、コーディング
  • メール文面を作成

手順(パスワードリセットの場合)

通知クラスの作成

artisanを利用してまずは空で作る。中身は後の手順で書く。

$ php artisan make:notification PasswordResetNotification
Notification created successfully.

これで app/Notifications/PasswordResetNotification.php が作成される。

Userクラスの通知関数をオーバーライド

既存のUserモデルクラスに対して、以下のオーバーライド処理を追記する。

app/User.php
    /**
     * Override to send for password reset notification.
     *
     * @param [type] $token
     * @return void
     */
    public function sendPasswordResetNotification($token)
    {
        $this->notify(new PasswordResetNotification($token));
    }

通知クラスの中身をコーディング

1からNotificationクラスを書いても良いけど、折角なのでデフォルトで導入されて使われている ResetPassword クラスをパクr……継承して使わせてもらう。
まずは全文がこちら。

app/Notifications/PasswordResetNotification.php
<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Auth\Notifications\ResetPassword;

class PasswordResetNotification extends ResetPassword
{
    use Queueable;

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        if (static::$toMailCallback) {
            return call_user_func(static::$toMailCallback, $notifiable, $this->token);
        }

        return (new MailMessage)
                    ->subject('パスワードリセット通知')
                    ->view('emails.password_reset', [
                        'reset_url' => url(config('app.url').route('password.reset', ['token' => $this->token, 'email' => $notifiable->getEmailForPasswordReset()], false))
                    ]);
    }
}

順に解説する。
make:notification 時でデフォルトで書かれている内容は割愛するが、以下の関数は不要なので削除してしまう(オーバーライドの必要性がない)。

  • __construct()
  • via()
  • toArray()

次に use について。

use Illuminate\Auth\Notifications\ResetPassword;

こちらを追加しておく。
今回のカスタマイズをしない場合に使用されるのがこのクラスなので、つまりこれをありがたく流用させてもらうことで、がっつりと手間を省いてしまう。
なので extends の部分も、

class PasswordResetNotification extends ResetPassword

としておく。
もとは extends Notification だがここを流用するクラスに変えておく。

あとはメール送信部分である toMail() だけコーディングしてあげれば良い。

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        if (static::$toMailCallback) {
            return call_user_func(static::$toMailCallback, $notifiable, $this->token);
        }

        return (new MailMessage)
                    ->subject('パスワードリセット通知')
                    ->view('emails.password_reset', [
                        'reset_url' => url(config('app.url').route('password.reset', ['token' => $this->token, 'email' => $notifiable->getEmailForPasswordReset()], false))
                    ]);
    }

if文部分は流用元そのままなので、そのまま利用。

件名を ->subject() の引数に入れておき、メールで送りたいViewを ->view() で指定してあげればOK。
ここでは 'emails.password_reset' を指定しているので、 resources/views/emails/password_reset.blade.php がViewとして扱われてメールで送られていく、ということになる。

view() 指定で送るようにすれば、Bladeテンプレートが利用できるのでとても便利。
第2引数にはArrayで変数を送ることもできる。上記の例でリンクURLとして使用するための url(config('app.url').~~ としている部分は、流用元そのままなので深く考えずにコピペで良いと思う。

メール文面の作成

あとは普段通りにViewを作るだけ!

手順(メール認証の場合)

基本的にはパスワード認証と同じ。以下の点が異なるだけ。

  • 継承元クラスは VerifyEmail になる。
    • use Illuminate\Auth\Notifications\VerifyEmail; になる。
  • toMail() のコードは以下のような感じ。
    public function toMail($notifiable)
    {
        $verificationUrl = $this->verificationUrl($notifiable);

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

        return (new MailMessage)
                    ->subject('メール認証')
                    ->view('emails.email_verify', [
                        'verify_url' => $verificationUrl
                    ]);
    }
  • view側で verify_url の変数参照する際は {{ $verify_url }} ではなく {!! $verify_url !!} とする。URL内にアンパサンドが入ってくるので。

参考:Framework側のコード

困ったらFramework側のコードを見てしまうと参考になるかも。
このあたり。

  • vendor\laravel\framework\src\Illuminate\Auth\Notifications
    • ResetPassword.php
    • VerifyEmail.php
  • vendor\laravel\framework\src\Illuminate\Notifications\resources\views
    • email.blade.php

単に日本語化するだけであれば、今回のような手間をかけなくても、上記のファイルを見ながら resources\lang\ja.json にゴリゴリと対訳を書いてしまうだけでも良い。

参考URL

13
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?