こんにちは。Laravelには標準の認証機能Authが用意されており、その中にはパスワードリセット機能が最初から含まれています。 メールアドレスを入力するとメールが送信され、メール本文内のURLにアクセスしてパスワードを再設定できるという、様々なサイトにある機能です。
今回はこのパスワードリセット機能を一部カスタマイズすることで、Laravelの認証機能のカスタマイズ方法を追っていきたいと思います。
環境はmacOS High Sierra+Laradockで構築し、LaravelのバージョンはLTS版の最新である5.5を使用します。また、Docker本体のインストール完了、およびLaradockで環境構築しWelcomeページが表示できていることが前提となります。
ログイン画面等のviewは、Laravel標準で提供されているauth
を利用します。PHPが動作しているコンテナにログインし、artisan
コマンドを実行することで自動生成できます。
# コンテナにログイン $ docker-compose exec --user=laradock workspace bash # authインストール $ php artisan make:auth Authentication scaffolding generated successfully.
mailhogは簡易SMTPサーバの一種で、mailhogに対してPHPやRubyなどからメール送信処理を実行することで、実際のアドレスに送信することなく、メールの内容を確認することができます。 mailhogのコンテナはLaradockに含まれており、build&upで簡単に立ち上げることができます。
$ docker-compose build --no-cache mailhog
Building mailhog Step 1/4 : FROM mailhog/mailhog ... ... Successfully built f1f39fbd927d Successfully tagged laradock_mailhog:latest $ docker-compose up -d mailhog Recreating laradock_mailhog_1 ... done
立ち上げた後はlocalhost:8025
にアクセスすると、mailhogに送信したメールをブラウザから確認できます。なお、mailhogの設定はdocker-compose.ymlに記述されており、デフォルトでは下記のようになっています。
この場合、1025番ポートでメールを待ち受けており、8025番ポートでブラウザからのアクセスを待ち受けているという意味になります。
mailhog: build: ./mailhog ports: - "1025:1025" - "8025:8025" networks: - frontend - backend
続いてLaravelのメール送信設定を変更します。Laravelプロジェクトのトップディレクトリにある.env
を編集し、デフォルトから以下のように変更します。
MAIL_DRIVER=smtp MAIL_HOST=smtp.mailtrap.io → mailhog MAIL_PORT=2525 → 1025 MAIL_USERNAME=null → user MAIL_PASSWORD=null → password MAIL_ENCRYPTION=null
これでLaravelから送信されるメールをmailhogでキャッチし、実際にメールアドレスに送信することなくメール内容を確認できるようになりました。
localhost/register
にアクセスすると登録フォームが表示されます。 任意のアカウント名・メールアドレス・パスワードを入れて登録を行い、ログイン完了した旨が表示されたら、画面右上のリンクからログアウトしましょう。
http://localhost/login
で「Forgot Your Password?」をクリックすると、メールアドレス入力画面が表示されます。 デフォルトではここで入力したメールアドレスにパスワードリセット用のURLが送信されますが、今回はアカウント名でリセットを行うようにカスタマイズしてみます。
「どのURLにアクセスしたらどのアクションメソッドが呼ばれるか」を確認するにはいくつか方法がありますが、ここではartisan
コマンドを使います。
$ php artisan route:list +--------+----------+------------------------+------------------+------------------------------------------------------------------------+--------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+----------+------------------------+------------------+------------------------------------------------------------------------+--------------+ | | GET|HEAD | / | | Closure | web | | | GET|HEAD | api/user | | Closure | api,auth:api | | | GET|HEAD | home | home | App\Http\Controllers\HomeController@index | web,auth | | | GET|HEAD | login | login | App\Http\Controllers\Auth\LoginController@showLoginForm | web,guest | | | POST | login | | App\Http\Controllers\Auth\LoginController@login | web,guest | | | POST | logout | logout | App\Http\Controllers\Auth\LoginController@logout | web | | | POST | password/email | password.email | App\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail | web,guest | | | GET|HEAD | password/reset | password.request | App\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm | web,guest | | | POST | password/reset | | App\Http\Controllers\Auth\ResetPasswordController@reset | web,guest | | | GET|HEAD | password/reset/{token} | password.reset | App\Http\Controllers\Auth\ResetPasswordController@showResetForm | web,guest | | | GET|HEAD | register | register | App\Http\Controllers\Auth\RegisterController@showRegistrationForm | web,guest | | | POST | register | | App\Http\Controllers\Auth\RegisterController@register | web,guest | +--------+----------+------------------------+------------------+------------------------------------------------------------------------+--------------+
メールアドレス入力画面のURLはpassword/resetですので、対応しているのは下記の行となります。
GET|HEAD | password/reset | password.request | App\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm
ところがForgotPasswordController
を開いてみるとshowLinkRequestForm
は存在せず、実際の処理はSendsPasswordResetEmails
のshowLinkRequestFormで行われています。 これでauth/passwords/email.blade.php
を呼び出しているのが分かりました。viewのファイル名を変えたり、viewを呼び出す以外の処理を行いたい場合はForgotPasswordController
クラスでshowLinkRequestForm
をオーバーライドすることでカスタマイズが可能です。
trait SendsPasswordResetEmails { public function showLinkRequestForm() { return view('auth.passwords.email'); } ... ...
auth/passwords/email.blade.php
を以下のように編集し、メールアドレスではなくアカウント名を入れるようにします。
@if ($errors->has('name')) {{ $errors->first('name') }} @endif
viewの編集が完了したら、ユーザー登録したときのアカウント名を入力して「Send Password Reset Link」を…と言いたいところですが、本来はメールアドレスの入力を想定した機能ですので、アカウント名を入力しても動作せず、エラー扱いになってしまいます。認証部分の処理もカスタマイズしましょう。
auth/passwords/email.blade.php
のform要素を見ると、送信先はpassword/email
が指定されています。