環境構築からWEBアプリ開発・スマホアプリ開発まで。ときには動画制作やゲームも。

supilog
すぴろぐ

2要素認証も簡単?Laravel Jetstreamを使ってみるテスト(laravel9)

2要素認証も簡単?Laravel Jetstreamを使ってみるテスト(laravel9)

Laravel Jetstreamを使ったことがないので、主に自分用のメモとして残します。

#Laravel Jetstream

Laravel Jetstream is a beautifully designed application starter kit for Laravel and provides the perfect starting point for your next Laravel application. Jetstream provides the implementation for your application’s login, registration, email verification, two-factor authentication, session management, API via Laravel Sanctum, and optional team management features.

Jetstream is designed using Tailwind CSS and offers your choice of Livewire or Inertia scaffolding.

#Available Stacks

Laravel Jetstream offers your choice of two frontend stacks: Livewire and Inertia.js. Each stack provides a productive, powerful starting point for building your application; however, the stack you choose will depend on your preferred templating language.

Jetstream公式 https://jetstream.laravel.com/2.x/introduction.html

google翻訳様ありがとうございます。

#Laravel Jetstream

Laravel Jetstream は、Laravel 用に美しく設計されたアプリケーション スターター キットであり、
次の Laravel アプリケーションの出発点として最適です。
Jetstream は、アプリケーションのログイン、登録、メール認証、2要素認証、セッション管理、Laravel Sanctum を
介した API、およびオプションのチーム管理機能の実装を提供します。

Jetstream は Tailwind CSS を使用して設計されており、 Livewire または Inertia の足場を選択できます。

#Available Stacks

Laravel Jetstream では、Livewire と Inertia.js の 2 つのフロントエンド スタックから選択できます。
各スタックは、アプリケーションを構築するための生産的で強力な開始点を提供します。
ただし、選択するスタックは、好みのテンプレート言語によって異なります。

Breezeと比べて、より高度は機能を有しているみたいですね。

さて、早速ですが、インストールしてみます。

インストール

今回使用するLaravelのバージョンは9.5.2です。

$ composer create-project laravel/laravel:^9.0 example-app
$ cd example-app
$ composer require laravel/jetstream

「Livewire + Blade」か「Inertia + Vue」を選べるようだったので、今回は「Livewire + Blade」を選択。チーム管理オプションなども付けれるが、最初は混乱するので付けない。

$ php artisan jetstream:install livewire

DB接続がないと表示確認できないようなので、一旦DBをsqliteにして確認してみる。

$ touch database/database.sqlite
DB_CONNECTION=sqlite
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=laravel
# DB_USERNAME=root
# DB_PASSWORD=

migrateして、アプリ確認してみます。

$ php artisan migrate
$ npm run build

$ php artisan serve

Breezeで実装されているような基本機能はこれで、一通り揃っているみたい。

ちゃんと動いてます。

ルートやコントローラを見てみるとファイルがない

ないんですね。ルートも追加されているのは、ダッシュボード画面のみ。app/Http/Controllers配下に追加されたファイルは0です。

ここで公式ドキュメントをみてみると。

Laravel Breezeとは対照的に、Laravel Jetstream はコントローラーやルートをアプリケーションに公開しません。代わりに、Jetstream の機能は「アクション」クラスを介してカスタマイズされます。Jetstream のインストール プロセス中に、アクションがアプリケーションのapp/Actionsディレクトリに公開されます。

https://jetstream.laravel.com/3.x/concept-overview.html#introduction

一応1個だけでも追ってみますか。ということで、/loginで表示されるログイン画面が表示されるまでの流れを追ってみる。

ログイン画面表示までの流れを理解してみる

ルートを追え!

$ php artisan route:list
GET|HEAD  login ........... login › Laravel\Fortify › AuthenticatedSessionController@create

ルートのファイルがないとはいえ、ルートの記述はどこかにあるはずだということで、この記述を探しまして、見つけました。長いので省略して表示しますが、こちらです。

...

Route::group(['middleware' => config('fortify.middleware', ['web'])], function () {
    $enableViews = config('fortify.views', true);

    // Authentication...
    if ($enableViews) {
        Route::get('/login', [AuthenticatedSessionController::class, 'create'])
            ->middleware(['guest:'.config('fortify.guard')])
            ->name('login');
    }

...

このファイルが呼ばれているのが、ここ。

...
    protected function configureRoutes()
    {
        if (Fortify::$registersRoutes) {
            Route::group([
                'namespace' => 'Laravel\Fortify\Http\Controllers',
                'domain' => config('fortify.domain', null),
                'prefix' => config('fortify.prefix'),
            ], function () {
                $this->loadRoutesFrom(__DIR__.'/../routes/routes.php');
            });
        }
    }

...

とりあえず、こいつらの記述によって、見えないルートが登録されているのだということが分かる。

表示までの処理を追え!

ルートは登録されたものとして向き先は、「AuthenticatedSessionController@create」。コントローラを見てみる。

    public function create(Request $request): LoginViewResponse
    {
        return app(LoginViewResponse::class);
    }

んーと、サービスコンテナに登録されたLoginViewResponse::classを返却しているのでしょうか。LoginViewResponseクラスを見にいっても、インターフェスなので何も記述されていません。LoginViewResponse::classが登録されている箇所を探します。

    public static function loginView($view)
    {
        app()->singleton(LoginViewResponse::class, function () use ($view) {
            return new SimpleViewResponse($view);
        });
    }

引数の$viewを保存したSimpleViewResponseインスタンスをsingletonで登録している処理のようです。これが呼ばれているところを見てみます。

    public static function viewPrefix(string $prefix)
    {
        static::loginView($prefix.'login');
        static::twoFactorChallengeView($prefix.'two-factor-challenge');
        static::registerView($prefix.'register');
        static::requestPasswordResetLinkView($prefix.'forgot-password');
        static::resetPasswordView($prefix.'reset-password');
        static::verifyEmailView($prefix.'verify-email');
        static::confirmPasswordView($prefix.'confirm-password');
    }

さらに、これが呼ばれているのが、ここ。

...

    public function boot()
    {
        Fortify::viewPrefix('auth.');

        $this->configurePublishing();
        $this->configureRoutes();

...

ということで、「JetstreamServiceProvider」によって、「Fortify::viewPrefix(‘auth.’);」がコールされていて、この処理で、auth.loginを含めた7画面がシングルトンのインスタンスとして、登録されており、アクセスした時に、SimpleViewResponseインスタンスのtoResponse内の処理でビューが返却されている流れのようです。

特定の処理を削除したい場合は・・・

コントローラーやルートを公開しないポリシーは良いとして、不要な機能を削除したい時はどうすれば良いか。ルートさえ消せれば良いので、JetstreamないしはFortifyのignoreRoutesを呼び出して、自分でルート設定を記述するという感じでしょうか。

# 設定例 こんな感じで呼び出せば自動設定されていたルートは消えるはず。
# 別途必要なルート設定を自分で記述する

class FortifyServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        Jetstream::ignoreRoutes();
        Fortify::ignoreRoutes();
    }
...
}

ブラウザセッション

ダッシュボード画面にいって、プロフィール画面を開くと、自分のアカウントに紐付いたブラウザーセッションが表示される機能が付いています。必要に応じて特定のセッションを破棄したりできるんですね。なるほどなるほど。

2要素認証

Jetstreamを試しているからには、絶対試しておきたいのは2要素認証機能。せっかくなのでちょっとやってみました。

Google Authenticatorをスマホにインストールする

事前準備として、インストールしておきます。

2要素認証を有効にする

ダッシュボードからプロフィール画面に行きます

プロフィール画面から、「Two Factor Authentication」の「ENABLE」ボタンを押します

表示されたQRコードをインストールしたGoogle Authenticatorで読み取ってみます。

読み取ると、アプリ上に、コードが表示されるので、そのコードをWEBアプリ上の「Code欄」に入力します。

成功すると、↓のような表示になります。

この状態で、一度ログアウトし、再度ログインをしてみます。

メールアドレスとパスワードを入力後、コード入力画面が表示されました。

ここで、Google Authenticatorを開いて、現在表示されている6桁のコードを入力します。(コードは短時間で更新されます)無事にログインすることが確認できました!

これは予想以上に何もしなくて良くてびっくり。すんなり出来ました。

まとめ

今回は取り上げてませんが、API向けの軽量な認証システム、チーム管理という機能も特徴としてあげられていますので、機会があれば触れてみたいと思います。

いかがでしたか。2要素認証を構築したい方は、ものすごく簡単に導入できると思います。ぜひ導入してみてください。

それでは。