RitoLabo

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

  • 公開:
  • 更新:
  • カテゴリ: PHP Laravel
  • タグ: PHP,Laravel,5.5,5.4,5.3,Mail,Auth,Notification,5.6

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

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

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

アジェンダ
  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.phplaravel/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フレームワークが持つ基本機能をカスタマイズするには多少のコツが必要ですが、少しコードを読み進めれば意外とすんなりわかったりするので、是非試してみてください。