実現したいこと(抽象)
Laravelが提供しているFacadeで呼び出すクラスを差し替えたい。
処理の一部だけを変更したいのでLaravelが提供するクラスをオーバーライドしたい。
実現したいこと(具体)
Laravel Breezeを利用している。
自動生成されたパスワードリセット画面にてメールアドレスを入力して送信すると、存在チェックしてパスワードリセット用のメールを送信する。
存在チェックだけではなくて、権限チェックを追加して特定のユーザ権限の場合はエラー(メールアドレス誤りと同様に存在チェックエラー)としたい。
対応方法
app.php
でプロバイダを独自拡張のプロバイダに差し替え。
'providers' => [
//Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
App\Providers\PasswordResetServiceProvider::class,
独自拡張のプロバイダを作成。
extends PasswordsPasswordResetServiceProviderしているので、オーバーライドしたいメソッドのみ記載。
registerPasswordBrokerメソッドのPasswordBrokerManager
を独自拡張のものに差し替える(use App\Extensions\Auth\Passwords\PasswordBrokerManager
を利用する)
<?php
namespace App\Providers;
use App\Extensions\Auth\Passwords\PasswordBrokerManager;
use Illuminate\Auth\Passwords\PasswordResetServiceProvider as PasswordsPasswordResetServiceProvider;
class PasswordResetServiceProvider extends PasswordsPasswordResetServiceProvider
{
/**
* Register the password broker instance.
*
* @return void
*/
protected function registerPasswordBroker()
{
$this->app->singleton('auth.password', function ($app) {
return new PasswordBrokerManager($app);
});
$this->app->bind('auth.password.broker', function ($app) {
return $app->make('auth.password')->broker();
});
}
}
プロバイダから呼び出される拡張PasswordBrokerManagerを作成
extendsするのでオーバーライドしたいメソッドのみ記載。
今回は独自のPasswordBrokerを使いたいのでresolveメソッドのみ書き換え。
<?php
namespace App\Extensions\Auth\Passwords;
use Illuminate\Auth\Passwords\PasswordBrokerManager as PasswordsPasswordBrokerManager;
use InvalidArgumentException;
/**
* @mixin \Illuminate\Contracts\Auth\PasswordBroker
*/
class PasswordBrokerManager extends PasswordsPasswordBrokerManager
{
/**
* Resolve the given broker.
*
* @param string $name
* @return \Illuminate\Contracts\Auth\PasswordBroker
*
* @throws \InvalidArgumentException
*/
protected function resolve($name)
{
$config = $this->getConfig($name);
if (is_null($config)) {
throw new InvalidArgumentException("Password resetter [{$name}] is not defined.");
}
// App\Extensions\Auth\Passwords配下のものでnewする
return new PasswordBroker(
$this->createTokenRepository($config),
$this->app['auth']->createUserProvider($config['provider'] ?? null)
);
}
}
権限チェックを行う拡張PasswordBrokerを作成
やっと権限チェックを入れたいPasswordBroker。
ここも今までと同じようにextends PasswordsPasswordBroker
して、特定のメソッドのみオーバーライドする。
今回はsendResetLinkメソッドに権限チェックをして問題なければ、親のsendResetLinkを呼ぶ。(parent::sendResetLink
)
<?php
namespace App\Extensions\Auth\Passwords;
use Closure;
use Illuminate\Auth\Passwords\PasswordBroker as PasswordsPasswordBroker;
class PasswordBroker extends PasswordsPasswordBroker
{
public function sendResetLink(array $credentials, Closure $callback = null)
{
$user = $this->getUser($credentials);
// ここに権限チェックを追加
if (is_null($user) || $user->is_xxx) {
return static::INVALID_USER;
}
return parent::sendResetLink($credentials, $callback);
}
}
参考
以下、ありがとうございます!
メール送信で同じようなことをしている。
https://stackoverflow.com/questions/39102483/add-a-new-transport-driver-to-laravels-mailer/39104567#39104567
ヘルパ関数で同じようなことをしている。
Extensions
ディレクトリを作るのが自分もしっくりきた。
https://qiita.com/kd9951/items/46ef3559009ee575ea7d