【Laravel 11】ログイン認証後に共通処理を実装したい。

こんにちは
日本語ドキュメントはよ。
只野です。

Laravel 11」とスターターパッケージで「Jetstream」を利用して最近開発している私です。

フレームワークで色々できて便利なのですが、最新バージョンを使うとなると情報がまーすくない。

公式ドキュメントは日本語対応していないので、Google翻訳で読むわけですが。

結構わけわからん状態になるんですよ!

メソッド名とかも日本語に変換されたりするので結構ごちゃごちゃな文書になったりします。

なのでやりたいことを調べたいときにサクッっと情報が出てこないんですよね。

更新さん。お願いします。日本語ドキュメントも作ってください。

そんで今回は“ログインの後に共通処理”を実装したかったのです。

前のバージョンの情報は出てくるのですが、最新バージョンの「laravel 11」だと情報がWeb検索だとないんですよね~

スターターパッケージで「Jetstream」を利用しているというのもあります。

仕方ないので公式ドキュメントをGoogle翻訳でどうにかこうにか読んで、下記実装で認証後に処理を実装できました。

1:後処理用のクラスを作成

まずは後処理で実行したい処理をクラス化します。

PHPの無名関数でも実装はできますが、管理を考えるとクラス化する事がおすすめです。

クラスを作成するにはルールがあり、ルール通りに実装しないと動作しません。

主には下記のように実装します。

<?php

namespace App\System;

use App\Traits\TempFileTrait;

class PostAuthenticationProcessing
{
    use TempFileTrait;

    public function __construct()
    {

    }

    public function handle($request, $next)
    {
        //■ 一時ファイル削除
        $this->deleteTempDirectory();
        return $next($request);
    }
}

ネームスペース、クラス名はなんでもよいです。自身でお好みを設定します。

重要なのは「public function handle($request, $next)」このメソッドをクラス内に必ず実装してください。

そしてメソッド内の最後に「return $next($request);」の実装を必ず行います。

これがルールとなります。後は好きに実装します。今回の例だと一時ファイルを削除する処理を組み込んでいます。

2:Jetstreamのサービスプロバイダーを修正

次に「Jetstream」の処理を修正します。

Jetstream」には“認証パイプライン”という、認証処理の順序が管理されています。

この順序に独自で実装したクラスを追加することで、認証後に独自の共通処理を行う事ができます。

ドキュメントルート\app\providers\JetstreamServiceProvider.php

<?php

namespace App\Providers;

use App\Actions\Jetstream\AddTeamMember;
use App\Actions\Jetstream\CreateTeam;
use App\Actions\Jetstream\DeleteTeam;
use App\Actions\Jetstream\DeleteUser;
use App\Actions\Jetstream\InviteTeamMember;
use App\Actions\Jetstream\RemoveTeamMember;
use App\Actions\Jetstream\UpdateTeamName;
use App\Models\User;
use App\System\PostAuthenticationProcessing;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Hash;
use Laravel\Jetstream\Jetstream;
// 1 ここから
use Illuminate\Http\Request;
use Laravel\Fortify\Fortify;
use Laravel\Fortify\Actions\AttemptToAuthenticate;
use Laravel\Fortify\Actions\EnsureLoginIsNotThrottled;
use Laravel\Fortify\Actions\PrepareAuthenticatedSession;
use Laravel\Fortify\Actions\RedirectIfTwoFactorAuthenticatable;
// 1 ここまで追加

class JetstreamServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        //
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        $this->configurePermissions();

        Jetstream::createTeamsUsing(CreateTeam::class);
        Jetstream::updateTeamNamesUsing(UpdateTeamName::class);
        Jetstream::addTeamMembersUsing(AddTeamMember::class);
        Jetstream::inviteTeamMembersUsing(InviteTeamMember::class);
        Jetstream::removeTeamMembersUsing(RemoveTeamMember::class);
        Jetstream::deleteTeamsUsing(DeleteTeam::class);
        Jetstream::deleteUsersUsing(DeleteUser::class);

// 2 ここから
        // ■認証パイプラインのカスタマイズ(後処理を追加
        Fortify::authenticateThrough(function (Request $request) {
            return array_filter([
                    config('fortify.limiters.login') ? null : EnsureLoginIsNotThrottled::class,
                    RedirectIfTwoFactorAuthenticatable::class,
                    AttemptToAuthenticate::class,
                    PrepareAuthenticatedSession::class, // このクラス以降に独自で実装したクラスを追加する。
                    PostAuthenticationProcessing::class, // これが「1:後処理用のクラスを作成」で実装したクラス
            ]);
        });
// 2 ここまで追加

        // ■認証処理のカスタマイズ
        Fortify::authenticateUsing(function (Request $request) {
            $user = User::where('user_id', $request->userId)->first();
    
            if ($user &&
                Hash::check($request->password, $user->password)) {
                return $user;
            }
        });
    }

    /**
     * Configure the roles and permissions that are available within the application.
     */
    protected function configurePermissions(): void
    {
        Jetstream::defaultApiTokenPermissions(['read']);

        Jetstream::role('admin', '管理者', [
            'create',
            'read',
            'update',
            'delete',
            'team',
        ])->description('システム管理者です。全ての機能が利用できます。');

        Jetstream::role('general', '一般', [
            'create',
            'read',
            'update',
            'delete',
        ])->description('一般利用者用権限です。');
    }
}

認証パイプラインのカスタマイズは必要な参照を増やし、「public function boot(): void」メソッド内に、認証パイプラインの定義を追加する必要があります。

これで認証後に独自の処理を動作させることができます。ですが問題もあります。

このカスタマイズはログイン画面を通して認証した場合なので、例えばLaravelの「認証情報を保存する」などの機能を利用して認証情報が保存されている場合は、この認証パイプラインは通りません。

この動きはなんでなんだろうね?と思うところです。システム的に認証情報が保存されているだけで、認証はしてるでしょと思う私です。

ここについても後々調べたいところです。

本日はこの辺で

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です