Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
11
Help us understand the problem. What is going on with this article?
@daijin

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

やりたいこと

  • 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

11
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
daijin
しがないゲーマー。三度の飯よりゲームが好き。DTMとかときどきする。本業はC/C++で何か作ってたけど、最近はラズパイとかLaravelとか触ってる。Unityも始めました。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
11
Help us understand the problem. What is going on with this article?