【PHP/Laravel】guard 認証で処理を別途かませたい

php-laravel

状況

  • 例えば、ログイン時に特定の条件を含む場合(ex. パスワードがある条件を満たす)に別処理をかませたいとき。homeにリダイレクトさせる前に、別途処理を加えたい。

fortify, guard

  • Fortifyの場合、デフォルトで認証のバックエンドが揃ってる。
  • FortifyServiceProvider.phpで、fortifyに指示を出すが、当初middlewareを自作して、そこで余計に認証処理を繰り返してしまっていた。この時、\laravel\fortify\routes\routes.phpを参考に、カスタマイズしやすいようにweb.phpに余計にルーティングして、一体どこを通っているのか良く分からなくなった。
  • このルーティングは不要で、既に用意されてるfortifyのログイン周りをそのまま使う。一応カスタムする場合には、名前付きルートはそのままの状態で使用した方がスッキリするしエラーも出にくい。
  • middlewareで自作した処理自体は問題無くて、Actionsなどの別ファイルに移行させておく。
  • fortifyはconfig/fortify.phpで使用するguardをカスタムできる。ただし、ガードにはIlluminate\Contracts\Auth\StatefulGuardを確実に実装するように、との指示がある。
  • config/fortify.phpのガードは、デフォルトで「web」が設定されてる。これが何かというと、config/auth.phpに認証ガードの定義が書かれてあり、ガードに対応するプロバイダーについてもここに記載がある。
  • デフォルトはusersになっており、例えばテーブル自体を変更する場合には、usersを各々変更したいテーブル名に変更する。基本はセッションがサポートされてて、プロバイダーのドライバーにはeloquentを使用して、usersから認証情報を取得する。
//Authentication Guards
'guards' => [
  'web' => [
     'driver' => 'session',
     'provider' => 'users',
  ],
],
//User Providers
'Providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\Models\User::class,
    ],
],
  • 特定の処理をかませたいとき、src/Http/Controller/AuthenticatedSessionController.phpの中身が参考になる。
/**
     * The guard implementation.
     *
     * @var \Illuminate\Contracts\Auth\StatefulGuard
     */
    protected $guard;

    /**
     * Create a new controller instance.
     *
     * @param  \Illuminate\Contracts\Auth\StatefulGuard  $guard
     * @return void
     */
    public function __construct(StatefulGuard $guard)
    {
        $this->guard = $guard;
    }
  • $this->guardを、試しにdd()でデバッグしてみる。すると、user:App\Models\Userがある。
  • 指定されたテーブルusersで認証されたuserの情報が確認できることが分かる。ここで、$this->guard->user()としてやれば、認証時のidとか諸々の情報を得られる。これを利用してかませた処理を実行すれば、そのままhomeにリダイレクトさせたり、問題があるので、一旦別パスに送ることも出来る。
  • 導線をはっきりさせるために、FortifyServiceProvider.phpとweb.phpの記述に注意する。

参照

Laravel 9.x 認証
Laravel 9.x Laravel Fortify
laravel/fortify

Laravel, php, programming

Posted by 異世界攻略班