LoginSignup
17
15

More than 5 years have passed since last update.

Laravel マルチ認証にてパスワードリセットのメールのリンクがおかしかった。

Last updated at Posted at 2017-06-17

Laravel5.4でマルチ認証
とかを参考にマルチ認証を実装していたら、パスワードリセットのメールのリンク先がおかしかった。

やりたかったこと

  • /user 以下に一般ユーザ様用の認証付きページがある
  • /admin 以下に管理者様用の認証付きページある
  • Laravelが用意している php artisan make:auth を利用する
  • それぞれ Forgot Your Password? のリンク(下の画像)からパスワードをリセットできる
  • 受信したパスワードリセットのメールからは、userまたはadminかに応じて /user/password/reset/xxx/admin/password/reset/xxx にリンクする

スクリーンショット 2017-06-17 22.43.58.png

普通に実装した場合

↓のようなメールが届くのですが

スクリーンショット 2017-06-17 22.39.55.png

/user/password/reset/admin/password/reset それぞれで再発行し、受信したメールは両方とも、
/user/password/reset/xxx にリンクされてしまいました。

対応策

config/auth.php にadmin用の (passwords) brokerを設定したと思います。

config/auth.php



    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
        ],
        'admins' => [
            'provider' => 'admins',
            'table' => 'password_resets',
            'expire' => 60,
        ],
    ],


それを admin 用の ResetPasswordController に設定します。

Controllers/Admin/Auth/ResetPasswordController.php


    public function broker()
    {
        return \Password::broker('admins');
    }



ForgotPasswordController にも設定します。

Controllers/Admin/Auth/ForgotPasswordController.php


    public function broker()
    {
        return \Password::broker('admins');
    }



ここからがポイントです。
パスワードリセットメールは基本的に Illuminate\Auth\Notifications\ResetPasswordtoMail() によって発信されます。
これを頑張ってOverrideします。

まず、app 以下に app/Notifications のようにディレクトリを作成し、
ResetPassword classを継承した AdminPasswordResetNotification を作成します。

そうすると、 toMail() をOverrideできますので、そこで admin.password.reset のルーティングを打ち込みます。
以下のようにします。

app/Notifications/AdminPasswordResetNotification.php

<?php
namespace App\Notifications;
use Illuminate\Auth\Notifications\ResetPassword as ResetPasswordNotification;
use Illuminate\Notifications\Messages\MailMessage;

class AdminPasswordResetNotification extends ResetPasswordNotification
{
    public function toMail($notifiable)
    {
        return (new MailMessage)
            ->line('You are receiving this email because we received a password reset request for your account.')
            ->action('Reset Password', url(config('app.url').route('admin.password.reset', $this->token, false)))
            ->line('If you did not request a password reset, no further action is required.');
    }
}

これが作成できたら、今度は Admin モデルにて、 sendPasswordResetNotification メソッドをOverrideして、作成したクラスをぶちこみます。

app/Admin.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Notifications\AdminPasswordResetNotification;

class Admin extends Authenticatable
{
    use Notifiable;

    public function sendPasswordResetNotification($token)
    {
        $this->notify(new AdminPasswordResetNotification($token));
    }
}

これで動くはず

まとめ

とりあえず内部のコードを読んで適当にOverrideすればなんとかなる。

17
15
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
15