今回はLaravelでパスワードをユーザーのパスワードをリセットする機能を実装します。
開発環境
PHP 7.3.9
MAMP 5.7
Mysql 5.7.26
Laravel 6.20.7
Composer 2.0.8
ユーザー認証機能の実装及びDB接続
まずは認証機能を作成しておきましょう。
$ composer require laravel/ui "1.x" --dev
$ php artisan ui bootstrap --auth
$ npm install && npm run dev
次にDB接続。
.envファイルに環境変数を設定して、
$ php artisan migrate
もし上手く行かない方はこちらを参考にしてください。
【MAMP】laravelのMySQL接続エラー([1045] Access denied for user)
Laravelからメールを送信できるように設定
まずはLaravelでメールを送信できるようにしていないといけません。
今回はGmailのSMTPサーバーを用いて実装していきます。
Googleアカウントを準備
はじめにGoogleアカウントを用意してください。
用意したGoogleアカウントのGmailアドレスからパスワード再設定のメールを送信することになります。
安全性の低いアプリの許可を有効に設定
用意したGoogleアカウントの設定を変更します。
下記のリンクを押して使用する予定のGoogleアカウントに切り替えましょう。
その後、「安全性の低いアプリの許可」を有効にします。
安全性の低いアプリのアクセス
.envで環境変数を追加する
MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=<Gmailアドレス>
MAIL_PASSWORD=<Gmailパスワード>
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=<Gmailアドレス>
MAIL_FROM_NAME=<任意の名前>
MAIL_USERNAMEのところはGoogleアカウントのユーザーネームを入力してもメールが送信できなかったのでそのままメールアドレス入力したら送信できました。
送信できるかテストをする
ターミナルで下記のコマンド実行しましょう。
nullが帰って来れば成功です。
$ php artisan tinker
Psy Shell v0.10.8 (PHP 7.3.9 — cli) by Justin Hileman
>>> Mail::raw('test mail', function($message) {$message->to('<送信先アドレス>')->subject('Test');});
=> null
通知クラスを用いて再設定メールのテンプレートを作成する
app/Notifications/UserResetPassword.php
を生成します。
$ php artisan make:notification UserResetPassword
生成したapp/Notifications/UserResetPassword.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\Auth\Notifications\ResetPassword;
class UserResetPassword extends Notification
{
use Queueable;
/**
* The password reset token.
*
* @var string
*/
public $token;
/**
* Create a new notification instance.
*
* @param string $token
* @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('パスワード再設定')
->greeting('平素よりアプリをご利用いただきありがとうございます')
->line('下のボタンをクリックしてパスワードを再設定してください。')
->action(__('パスワードを再設定'), url(config('app.url').route('password.reset', $this->token, false)))
->line('もしこのメールに心当たりがない場合は、そのまま削除してください。');
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}
app/User.phpを編集する
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use App\Notifications\UserResetPassword;
class User extends Authenticatable
{
(略)
/**
* パスワードリセット通知の送信
*
* @param string $token
* @return void
*/
public function sendPasswordResetNotification($token)
{
$this->notify(new UserResetPassword($token));
}
}
最後に送られてきたメール内のパスワードの再設定用リンクのパスを修正。
->action(__('パスワードを再設定'), url(config('app.url').route('password.reset', $this->token, false)))
config('app.url')
であり、
デフォルトの設定だと、
APP_URL=http://localhost
となっているがこのままだとポート番号が記述されていないので再設定の画面が表示されない。
そのため自身のポート番号に合わせる必要がある
今回は8000番ポートなので
APP_URL=http://localhost:8000
とすればメール内の再設定画面へのリンクも問題なく遷移できるはずです。