今回はメールアドレスを入力せずにパスワードを変更する方法について、わかりやすく説明していきます。
また、なるべくコピペで実装できるようにコードをまるごと掲載していきます!
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 --devphp artisan ui vue --authnpm 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にてメールアドレスの入力なしでパスワードを更新する方法について解説しました。
他にも解説して欲しい内容があれば、是非ともコメント欄やお問い合わせからメッセージをください!
それでは!






コメント