今回はメールアドレスを入力せずにパスワードを変更する方法について、わかりやすく説明していきます。
また、なるべくコピペで実装できるようにコードをまるごと掲載していきます!
Laravelにデフォルトで実装されているパスワードリセット機能は非常に便利ですが、パスワード再設定画面でもう一度メールアドレスを入力する必要があり、二度手間です(一応自動で入力してくれますが)。
パスワード再設定画面
そこで、今回はメールアドレスを入力させずにパスワードの入力のみでパスワードの再設定を行います。
今回実装するメールアドレス変更機能の流れは以下の通りです。
ほとんどLaravelデフォルトのパスワードリセット機能を使います。
①ユーザーがメールアドレスを入力
②入力したメールアドレスあてにパスワード再設定メールを送信する
③メールのリンクからパスワード再設定フォームに遷移
④新しいパスワードのみを入力して、パスワードを再設定する
それではいきましょう!
開発環境
- MacBook Pro (macOS Catalina バージョン10.15.2)
- PHP 7.3.9
- Laravel Framework 6.13.1
Composerはすでにインストールしているとします。
メールアドレス変更の前準備
すでにプロジェクトを作成している場合は省略してください。
新規プロジェクト作成
まずは新規プロジェクトを作成します。
ターミナル
composer create-project --prefer-dist laravel/laravel PasswordResetWithoutEmailSample
プロジェクトのカレントディレクトリに移動して、ローカル開発サーバを立ち上げます。
ターミナル
php artisan serve
.envのAPP_URLにポート番号を追加しておいてください。
APP_URL=http://localhost:8000
http://127.0.0.1:8000
にアクセスします。
ページが正常に表示されていればOKです。
認証機能作成
コマンドで簡単に認証機能を作成します。
Laravel 6.0以降は認証機能実装手順が変更されているので注意してください。
- Laravel 5.8以前
ターミナル
php artisan make:auth
- Laravel 6.0以降
ターミナル
composer require laravel/ui --dev
php artisan ui vue --auth
npm install && npm run dev
認証機能が作成されると右上にLOGIN と REGISTERが追加されます。
マイグレーションしてテーブル作成&テストデータ挿入
シーダーファイルを作成し、以下のように修正します。
ターミナル
php artisan make:seeder UsersTableSeeder
UsersTableSeeder.php
<?php use Illuminate\Database\Seeder; class UsersTableSeeder extends Seeder { public function run() { DB::table('users')->insert([ [ 'name' => '田中太郎', 'email' => 'tanaka@example.com', 'password' => Hash::make('password'), ], ]); } }
DatabaseSeeder.phpを以下のように修正します。
<?php use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { /** * Seed the application's database. * * @return void */ public function run() { $this->call(UsersTableSeeder::class); } }
テーブルを作成して、データを挿入します。
ターミナル
php artisan migrate:fresh --seed
DBの状態はこんな感じです。
LOGINからメールアドレスとパスワードを入力すると無事ログインできました。
これで準備は完了です。
メールの受信テストの準備
メールを送信するためメールサーバーが必要ですが、今回はテスト送信で済ませるので、MailHogを使用します。
MailHogはメールのテストツールです。
MailHogをインストール&起動します。
ターミナルで
brew install mailhog
brew services start mailhog
Laravel側は.envの設定を以下のように修正します。
MAIL_DRIVER=smtp # MAIL_HOST=smtp.mailtrap.io MAIL_HOST=localhost # MAIL_PORT=2525 MAIL_PORT=1025 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null MAIL_FROM_ADDRESS=sender@example.com MAIL_FROM_NAME="${APP_NAME}"
.envの設定を変更したのでキャッシュをクリアしておきます。
ターミナル
php artisan config:cache
以下のURLにアクセスしてMailHogの画面が表示されれば成功です。
http://localhost:8025/
メールアドレス入力なしのパスワード再設定機能を実装する
それではパスワード再設定画面からメールアドレスフィールドを消していきます。
まずはパスワード再設定の流れを確認します。
「Forget Your Password?」をクリックします。
DBに登録しているメールアドレスを入力して、パスワード再設定メールを送信します。
MailHogで届いたメールを確認します。
「Reset Password」ボタンをクリックするとパスワード再設定画面に遷移します。
上記がデフォルトの流れになります。
この時のパスワード再設定画面のURLを確認すると、
このようにトークン+メールアドレスとなっています。
このURLパラメータを見て、パスワード再設定画面のreset.blade.phpに値を渡しています。
したがって、reset.blade.phpのメールアドレス入力フォームのtype属性をhiddenに設定することでメールアドレスフォームを非表示にすることが可能です。
具体的には以下のように修正します。
reset.blade.php
@extends('layouts.app') @section('content') <div class="container"> <div class="row justify-content-center"> <div class="col-md-8"> <div class="card"> <div class="card-header">{{ __('Reset Password') }}</div> <div class="card-body"> <form method="POST" action="{{ route('password.update') }}"> @csrf <input type="hidden" name="token" value="{{ $token }}"> <div class="form-group row"> <!-- <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label> --> <div class="col-md-6"> <input id="email" type="hidden" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ $email ?? old('email') }}" required autocomplete="email" autofocus> @error('email') <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> </div> <div class="form-group row"> <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label> <div class="col-md-6"> <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password"> @error('password') <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> </div> <div class="form-group row"> <label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label> <div class="col-md-6"> <input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password"> </div> </div> <div class="form-group row mb-0"> <div class="col-md-6 offset-md-4"> <button type="submit" class="btn btn-primary"> {{ __('Reset Password') }} </button> </div> </div> </form> </div> </div> </div> </div> </div> @endsection
メールアドレス入力フォームは非表示にしているので、E-Mail Addressのラベルも非表示にしてください。
これでパスワードを変更してみます。
テーブル初期状態は以下の通りです。
パスワード再設定画面ではメールアドレスが非表示になっています。
パスワードを入力して再設定します。
その後、テーブルを確認してみます。
パスワードのハッシュ値が変わり、 更新日が入力されているのでパスワードが正常に更新されたことがわかります。
今回はLaravelにてメールアドレスの入力なしでパスワードを更新する方法について解説しました。
他にも解説して欲しい内容があれば、是非ともコメント欄やお問い合わせからメッセージをください!
それでは!
コメント