1. Home
  2. PHP
  3. Laravel
  4. Laravelパスワードリセットメールの文面・デザインを変更する

Laravelパスワードリセットメールの文面・デザインを変更する

  • 公開日
  • 更新日
  • カテゴリ:Laravel
  • タグ:PHP,Laravel,Mail,Auth,Notification
Laravelパスワードリセットメールの文面・デザインを変更する

前回は Laravel の認証機能を導入し、ログイン、ユーザ登録、パスワードリセットなどの管理機能を実装しました。

しかしながら、実際の開発現場ではデフォルトのままで使えるという状況だけではありません。案件によって認証機能の拡張・カスタマイズが必要になってくる事も多々あります。

そこで今回は、Laravel の認証機能拡張第一弾として、パスワードリセット時のメールの文面・デザインの変更を行います。

Contents

  1. 開発環境
  2. パスワードリセットメールのカスタマイズ
    1. メールテンプレートの作成
    2. 通知(Notification)クラスの作成
    3. 通知クラスの切り替え
  3. 動作確認

開発環境

今回の開発環境は以下の通りです。

  • Linux CentOS 7
  • Apache 2.4
  • MySQL 5.7
  • PHP 7.1
  • Laravel 5.x

Laravel のバージョンに関しては 5.6/5.5/5.4/5.3 にて動作確認済みです。

また、laravel のルートディレクトリを「laravel/」とします。

認証機能は導入済みである前提で進めますので、導入までに関しては前回の記事である
Laravel の認証機能でログイン/ユーザ登録/パスワードリセットなどの管理画面を一撃構築する(基本&入門編)
を確認してください。

パスワードリセットメールのカスタマイズ

Laravel の認証機能にはパスワードリセット機能がありますが、デフォルトではリセットの為に送信されるメールは英語になっていますので、このままでは少々使いづらい面もあります。

そこで、メールを自由にカスタマイズして、要件に対して柔軟に対応できるようにします。

メールテンプレートの作成

まずはメールのテンプレートを作成します。

laravel/reources/views 配下に mail/html ディレクトリを作成し、その中に passwordreset.blade.php を作成します。

laravel
├─ resources
│   ├─ view
│   │   ├─ mail
│   │   │   ├─ html
│   │   │   │    └─ passwordreset.blade.php

作成した passwordreset.blade.php は以下のように記述しました。

laravel/reources/views/mail/html/passwordreset.blade.php
<!DOCTYPE html>
<html lang="ja">
<style>
  body { 
    background-color: #fffacd;
  }
  h1 {
    font-size: 16px;
    color: #ff6666;
  }
  #button {
    width: 200px;
    text-align: center;
  }
  #button a {
    padding: 10px 20px;
    display: block;
    border: 1px solid #2a88bd;
    background-color: #FFFFFF;
    color: #2a88bd;
    text-decoration: none;
    box-shadow: 2px 2px 3px #f5deb3;
  }
  #button a:hover {
    background-color: #2a88bd;
    color: #FFFFFF;
  }
</style>
<body>
<h1>
  パスワードリセット
</h1>
<p>
  以下のボタンを押下し、パスワードリセットの手続きを行ってください。
</p>
<p id="button">
  <a href="{{$reset_url}}">パスワードリセット</a>
</p>
</body>
</html>

シンプルな内容ですが一点だけ、変数 reset_url には、トークンパラメータを含めたリセット URL を送ります。

通知(Notification)クラスの作成

次に、通知(Notification)クラスを作成します。

Laravel ルートディレクトリへ移動し、以下の artisan コマンドを叩きます。

# Laravel ルートディレクトリへ移動する
cd /path/to/laravel

# artisan コマンドで Notification クラスを生成する
php artisan make:notification PasswordResetNotification

# 実行結果
[demo@localhost laravel]# php artisan make:notification PasswordResetNotification
Notification created successfully.

生成した PasswordResetNotification.php は laravel/app/Notifications 配下に生成されます。

laravel
├─ app
│   ├─ Notifications
│   │   └─ PasswordResetNotification.php

PasswordResetNotification.php の初期ソースは以下のようになっています。

<?php

namespace App\Notifications;

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

class PasswordResetNotification2 extends Notification
{
    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)
                    ->line('The introduction to the notification.')
                    ->action('Notification Action', url('/'))
                    ->line('Thank you for using our application!');
    }

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

これを、以下のように記述します。

<?php

namespace App\Notifications;

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

class PasswordResetNotification extends Notification
{
    use Queueable;

    public $token;
    protected $title = 'パスワードリセット 通知';

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct($token)
    {
      $this->token = $token;
    }

    /**
     * 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($this->title)
          ->view(
            'mail.html.passwordreset',
            [
              'reset_url' => url('password/reset', $this->token),
            ]);
    }

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

上から説明していきます。

public $token;
protected $title = 'パスワードリセット 通知';

メンバ変数を宣言しています。 token にはトークンを、 title にはご覧の通りメールのタイトルを設定します。

変数 title に関しては、パスワードリセットのメールという事で動的なものではないので、protected で宣言時に設定してしまっていますが、動的に設定したい場合はこれに限りません。

public function __construct($token)
{
  $this->token = $token;
}

コンストラクタです。ここで引数を受け取り、変数 token へ値をセットしています。変数 title を動的にしたい場合はトークンと同じくここでセットする流れにすれば OK です。

public function via($notifiable)
{
  return ['mail'];
}

ここは生成したデフォルトのままですが、Notification クラスはその名の通り「通知」を行うクラスなので、その手段をここで設定できます。デフォルトではメールになっているので、そのまま使用します。

public function toMail($notifiable)
{
    return (new MailMessage)
      ->subject($this->title)
      ->view(
        'mail.html.passwordreset',
        [
          'reset_url' => url('password/reset', $this->token),
        ]);
}

ここで通知の為のメールテンプレートやタイトルをセットしています。

デフォルトではそのままメール文を記述していますが、ここでは view メソッドを使ってテンプレートを指定しています。

第一引数にテンプレート、第二引数にテンプレートへ渡す値を指定しています。ここでは、トークンを含めたパスワードリセットページの RL を渡しています。

通知クラスの切り替え

メールテンプレートを作成し、それを用いての通知クラスを作成できたので、最後にこれらをデフォルトの通知クラスからこちらへ切り替えます。

Laravel ではもちろん、既にパスワードリセットの全てが実装されていますが、パスワードリセット通知を司る sendPasswordResetNotification メソッドをオーバーライド(上書き)する事で、通知クラスを切り替える事が出来ます。

laravel/app/User.php を開いて、下記のように sendPasswordResetNotification メソッドをオーバーライドします。

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Notifications\PasswordResetNotification;


class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];


    /**
     * パスワードリセット通知の送信をオーバーライド
     *
     * @param  string  $token
     * @return void
     */
    public function sendPasswordResetNotification($token)
    {
      $this->notify(new PasswordResetNotification($token));
    }
}

メソッドを追記するのはもちろんですが、新しく作成した通知クラス PasswordResetNotification を使用しているので、ファイルの冒頭で use するのを忘れないでください。

use App\Notifications\PasswordResetNotification;

動作確認

それでは動作確認を行います。
http://YOUR-DOMAIN/password/reset
にアクセスするとパスワードリセットのためのメールアドレス入力フォームが表示されますので、ユーザ登録済みのメールアドレスを入力してメールを受信してみます。

デフォルトのパスワードリセットメール自作のメールテンプレートに切り替わりました。これでパスワードリセットメールのカスタマイズ実装は完了です。

まとめ

以上で作業は完了です。 Laravel などの PHP フレームワークが持つ基本機能をカスタマイズするには多少のコツが必要ですが、少しコードを読み進めれば意外とすんなりわかったりするので、是非試してみてください。

Author

rito

  • Backend Engineer
  • Tokyo, Japan
  • PHP 5 技術者認定上級試験 認定者
  • 統計検定 3 級