Laravel5.4でマルチ認証
とかを参考にマルチ認証を実装していたら、パスワードリセットのメールのリンク先がおかしかった。
やりたかったこと
-
/user
以下に一般ユーザ様用の認証付きページがある -
/admin
以下に管理者様用の認証付きページある - Laravelが用意している
php artisan make:auth
を利用する - それぞれ Forgot Your Password? のリンク(下の画像)からパスワードをリセットできる
- 受信したパスワードリセットのメールからは、
user
またはadmin
かに応じて/user/password/reset/xxx
か/admin/password/reset/xxx
にリンクする
普通に実装した場合
↓のようなメールが届くのですが
/user/password/reset
と /admin/password/reset
それぞれで再発行し、受信したメールは両方とも、
/user/password/reset/xxx
にリンクされてしまいました。
対応策
config/auth.php
にadmin用の (passwords) brokerを設定したと思います。
・
・
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
'admins' => [
'provider' => 'admins',
'table' => 'password_resets',
'expire' => 60,
],
],
・
・
それを admin
用の ResetPasswordController
に設定します。
・
・
public function broker()
{
return \Password::broker('admins');
}
・
・
ForgotPasswordController
にも設定します。
・
・
public function broker()
{
return \Password::broker('admins');
}
・
・
ここからがポイントです。
パスワードリセットメールは基本的に Illuminate\Auth\Notifications\ResetPassword
の toMail()
によって発信されます。
これを頑張ってOverrideします。
まず、app
以下に app/Notifications
のようにディレクトリを作成し、
ResetPassword
classを継承した AdminPasswordResetNotification
を作成します。
そうすると、 toMail()
をOverrideできますので、そこで admin.password.reset
のルーティングを打ち込みます。
以下のようにします。
<?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して、作成したクラスをぶちこみます。
<?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すればなんとかなる。