結論
まだ終わっていないため引き続き二要素認証周りを調べていきますが、量が多いため、ひとまず途中経過を共有いたします。
別ページとかに分割するかもしれないです。
経緯
Laravel Fortify をAPIサーバーの認証システムに組み込もうとしましたが、下記理由により自分でエンドポイント周りを調べてみようと思います。
- エンドポイントのドキュメントが整備されていないと思われる
- 初見だと挙動がわかりづらい
- けれども、Starter Kitsを触った感じだと二要素認証とかデフォルトでできるし、導入したい
その他のFortifyで認証システムを組もうと思った理由はこちらで解説しています。
https://qiita.com/yasu_programming/items/de16c25aaa2ed961e51b
そういう理由でまとめてみようと思います。
調査方法
調査方法は以下の通りです。
- 調査用にLaravelのみのインストールをする
- エンドポイントを確認する
- Laravelをインストール && Starter Kitsを導入する
- エンドポイントを確認する
- LaravelのみとStarter Kitsを導入したものとエンドポイントの差分を調べる
- 画面と照らし合わせて、挙動を確認する
このような流れで調べようと思います。
調査用にLaravelのみのインストールをする
補足
下記が現在の私の諸々のバージョンです。
$ laravel --version
Laravel Installer 5.14.0
$ php -v
PHP 8.4.1
$ composer -v
______
/ ____/___ ____ ___ ____ ____ ________ _____
/ / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
/_/
Composer version 2.8.3
本題に戻ります
公式ドキュメント:https://laravel.com/docs/12.x/installation
に沿って進めていきます。
laravel new laravel-qiita
Which starter kit would you like to install? None
Which database will your application use? SQLite
Would you like to run npm install and npm run build? Yes
cd laravel-qiita
composer run dev
http://127.0.0.1:8000 でブラウザが動くことを確認。
エンドポイントを確認する
ターミナルの別タブで
cd laravel-qiita
php artisan route:list
GET|HEAD / ..............................
GET|HEAD storage/{path} ... storage.local
GET|HEAD up .............................
Laravelをインストール && Starter Kitsを導入する
こちらも同じく公式ドキュメント:https://laravel.com/docs/12.x/installation
に沿って進めていきます。
laravel new fortify-qiita
Which starter kit would you like to install? Vue
Which authentication provider do you prefer? Laravel's built-in authentication
Which testing framework do you prefer? PHPUnit
Would you like to run npm install and npm run build? Yes
laravel new fortify-qiita のときにいろいろ聞かれましたが、
Which starter kit would you like to install? 今回はVueを選択し(なんでもいいはずです。私が一番経験のある言語を選択しました。)、
Which authentication provider do you prefer? Laravel's built-in authentication を選択することで、Fortify での認証を使用することができます。詳しくはこちらですhttps://laravel.com/docs/12.x/starter-kits。
Which testing framework do you prefer? 今回関係ないですが、経験のあるPHPUnitを選択しました。
cd fortify-qiita
npm install && npm run build
composer run dev
http://127.0.0.1:8000/ で動くことを確認。
こちらには、RegisterやLog in という文字があることを確認。
エンドポイントを確認する
ターミナルの別タブで
cd fortify-qiita
php artisan route:list
GET|HEAD / ................................................................................................................ home
GET|HEAD dashboard ................................................................................................... dashboard
POST email/verification-notification ... verification.send › Laravel\Fortify › EmailVerificationNotificationController@store
GET|HEAD email/verify ....................... verification.notice › Laravel\Fortify › EmailVerificationPromptController@__invoke
GET|HEAD email/verify/{id}/{hash} ....................... verification.verify › Laravel\Fortify › VerifyEmailController@__invoke
GET|HEAD forgot-password ............................... password.request › Laravel\Fortify › PasswordResetLinkController@create
POST forgot-password .................................. password.email › Laravel\Fortify › PasswordResetLinkController@store
GET|HEAD login ................................................. login › Laravel\Fortify › AuthenticatedSessionController@create
POST login ............................................ login.store › Laravel\Fortify › AuthenticatedSessionController@store
POST logout .............................................. logout › Laravel\Fortify › AuthenticatedSessionController@destroy
GET|HEAD register ................................................. register › Laravel\Fortify › RegisteredUserController@create
POST register ............................................ register.store › Laravel\Fortify › RegisteredUserController@store
POST reset-password ........................................ password.update › Laravel\Fortify › NewPasswordController@store
GET|HEAD reset-password/{token} ................................ password.reset › Laravel\Fortify › NewPasswordController@create
ANY settings ...................................................................... Illuminate\Routing › RedirectController
GET|HEAD settings/appearance ................................................................................... appearance.edit
GET|HEAD settings/password ............................................... user-password.edit › Settings\PasswordController@edit
PUT settings/password ........................................... user-password.update › Settings\PasswordController@update
GET|HEAD settings/profile ....................................................... profile.edit › Settings\ProfileController@edit
PATCH settings/profile ................................................... profile.update › Settings\ProfileController@update
DELETE settings/profile ................................................. profile.destroy › Settings\ProfileController@destroy
GET|HEAD settings/two-factor ................................. two-factor.show › Settings\TwoFactorAuthenticationController@show
GET|HEAD storage/{path} .......................................................................................... storage.local
GET|HEAD two-factor-challenge .............. two-factor.login › Laravel\Fortify › TwoFactorAuthenticatedSessionController@create
POST two-factor-challenge ......... two-factor.login.store › Laravel\Fortify › TwoFactorAuthenticatedSessionController@store
GET|HEAD up ....................................................................................................................
GET|HEAD user/confirm-password ......................... password.confirm › Laravel\Fortify › ConfirmablePasswordController@show
POST user/confirm-password .................. password.confirm.store › Laravel\Fortify › ConfirmablePasswordController@store
GET|HEAD user/confirmed-password-status ....... password.confirmation › Laravel\Fortify › ConfirmedPasswordStatusController@show
POST user/confirmed-two-factor-authentication two-factor.confirm › Laravel\Fortify › ConfirmedTwoFactorAuthenticationContro…
POST user/two-factor-authentication .......... two-factor.enable › Laravel\Fortify › TwoFactorAuthenticationController@store
DELETE user/two-factor-authentication ....... two-factor.disable › Laravel\Fortify › TwoFactorAuthenticationController@destroy
GET|HEAD user/two-factor-qr-code ......................... two-factor.qr-code › Laravel\Fortify › TwoFactorQrCodeController@show
GET|HEAD user/two-factor-recovery-codes ............. two-factor.recovery-codes › Laravel\Fortify › RecoveryCodeController@index
POST user/two-factor-recovery-codes .. two-factor.regenerate-recovery-codes › Laravel\Fortify › RecoveryCodeController@store
GET|HEAD user/two-factor-secret-key ................ two-factor.secret-key › Laravel\Fortify › TwoFactorSecretKeyController@show
ものすごく増えている。
一つ一つ確認していくしかなさそうですので、確認していきます。
感覚的に画面とリンクしていそうなものを選別します。
http://127.0.0.1:8000/register
GET|HEAD register ................................................. register › Laravel\Fortify › RegisteredUserController@create
POST register ............................................ register.store › Laravel\Fortify › RegisteredUserController@store
http://127.0.0.1:8000/login
GET|HEAD login ................................................. login › Laravel\Fortify › AuthenticatedSessionController@create
POST login ............................................ login.store › Laravel\Fortify › AuthenticatedSessionController@store
http://127.0.0.1:8000/forgot-password
GET|HEAD forgot-password ............................... password.request › Laravel\Fortify › PasswordResetLinkController@create
POST forgot-password .................................. password.email › Laravel\Fortify › PasswordResetLinkController@store
http://127.0.0.1:8000/dashboard
GET|HEAD dashboard ................................................................................................... dashboard
POST logout .............................................. logout › Laravel\Fortify › AuthenticatedSessionController@destroy
http://127.0.0.1:8000/settings/profile
GET|HEAD settings/profile ....................................................... profile.edit › Settings\ProfileController@edit
PATCH settings/profile ................................................... profile.update › Settings\ProfileController@update
DELETE settings/profile ................................................. profile.destroy › Settings\ProfileController@destroy
http://127.0.0.1:8000/settings/password
GET|HEAD settings/password ............................................... user-password.edit › Settings\PasswordController@edit
PUT settings/password ........................................... user-password.update › Settings\PasswordController@update
Two-Factor Authをクリック
http://127.0.0.1:8000/user/confirm-password
GET|HEAD user/confirm-password ......................... password.confirm › Laravel\Fortify › ConfirmablePasswordController@show
POST user/confirm-password .................. password.confirm.store › Laravel\Fortify › ConfirmablePasswordController@store
passwordの認証ができると、下記URLに遷移される。
http://127.0.0.1:8000/settings/two-factor
GET|HEAD settings/two-factor ................................. two-factor.show › Settings\TwoFactorAuthenticationController@show
http://127.0.0.1:8000/settings/appearance
GET|HEAD settings/appearance ................................................................................... appearance.edit
http://127.0.0.1:8000/reset-password/abf122801e5f9278324fa01d41c4c48672d52b0badf589ed59214b3ebe089a9e?email=test%40test.com
POST reset-password ........................................ password.update › Laravel\Fortify › NewPasswordController@store
GET|HEAD reset-password/{token} ................................ password.reset › Laravel\Fortify › NewPasswordController@create
http://127.0.0.1:8000/two-factor-challenge
GET|HEAD two-factor-challenge .............. two-factor.login › Laravel\Fortify › TwoFactorAuthenticatedSessionController@create
POST two-factor-challenge ......... two-factor.login.store › Laravel\Fortify › TwoFactorAuthenticatedSessionController@store
エンドポイントの確認できていないものを整理
POST email/verification-notification ... verification.send › Laravel\Fortify › EmailVerificationNotificationController@store
GET|HEAD email/verify ....................... verification.notice › Laravel\Fortify › EmailVerificationPromptController@__invoke
GET|HEAD email/verify/{id}/{hash} ....................... verification.verify › Laravel\Fortify › VerifyEmailController@__invoke
ANY settings ...................................................................... Illuminate\Routing › RedirectController
GET|HEAD user/confirmed-password-status ....... password.confirmation › Laravel\Fortify › ConfirmedPasswordStatusController@show
POST user/confirmed-two-factor-authentication two-factor.confirm › Laravel\Fortify › ConfirmedTwoFactorAuthenticationContro…
POST user/two-factor-authentication .......... two-factor.enable › Laravel\Fortify › TwoFactorAuthenticationController@store
DELETE user/two-factor-authentication ....... two-factor.disable › Laravel\Fortify › TwoFactorAuthenticationController@destroy
GET|HEAD user/two-factor-qr-code ......................... two-factor.qr-code › Laravel\Fortify › TwoFactorQrCodeController@show
GET|HEAD user/two-factor-recovery-codes ............. two-factor.recovery-codes › Laravel\Fortify › RecoveryCodeController@index
POST user/two-factor-recovery-codes .. two-factor.regenerate-recovery-codes › Laravel\Fortify › RecoveryCodeController@store
GET|HEAD user/two-factor-secret-key ................ two-factor.secret-key › Laravel\Fortify › TwoFactorSecretKeyController@show
ユーザー登録時
https://reffect.co.jp/laravel/laravel-email-verification
この記事を参考にしましたが、ユーザー登録時に
app/Models/User.php
config/fortify.php
を調整することで、メール認証の処理ができるということでしたので、調整します。
app/Models/User.php
コメントアウトを外す
// use Illuminate\Contracts\Auth\MustVerifyEmail;
↓
use Illuminate\Contracts\Auth\MustVerifyEmail;
implements MustVerifyEmail を設定する
class User extends Authenticatable
↓
class User extends Authenticatable implements MustVerifyEmail
config/fortify.php
features にFeatures::emailVerification()があればOKなはずですので、デフォルトのままでOK。
'features' => [
Features::registration(),
Features::resetPasswords(),
Features::emailVerification(),
Features::twoFactorAuthentication([
'confirm' => true,
'confirmPassword' => true,
// 'window' => 0
]),
],
ユーザー登録してみる
遷移成功。
.envの設定で、MAIL_MAILER=logにしているため、storage/logs/laravel.logに内容が出力されるため、リンク先をクリックして確認してみる。
無事ダッシュボードに入ることに成功。
POST email/verification-notification ... verification.send › Laravel\Fortify › EmailVerificationNotificationController@store
GET|HEAD email/verify ....................... verification.notice › Laravel\Fortify › EmailVerificationPromptController@__invoke
GET|HEAD email/verify/{id}/{hash} ....................... verification.verify › Laravel\Fortify › VerifyEmailController@__invoke
この3つの挙動はユーザー登録時に確認できると思われる。
二要素認証
何個か直感的にわかりそうなものもあるが、コードを追ってみる。
ANY settings ...................................................................... Illuminate\Routing › RedirectController
GET|HEAD user/confirmed-password-status ....... password.confirmation › Laravel\Fortify › ConfirmedPasswordStatusController@show
POST user/confirmed-two-factor-authentication two-factor.confirm › Laravel\Fortify › ConfirmedTwoFactorAuthenticationContro…
POST user/two-factor-authentication .......... two-factor.enable › Laravel\Fortify › TwoFactorAuthenticationController@store
DELETE user/two-factor-authentication ....... two-factor.disable › Laravel\Fortify › TwoFactorAuthenticationController@destroy
GET|HEAD user/two-factor-qr-code ......................... two-factor.qr-code › Laravel\Fortify › TwoFactorQrCodeController@show
GET|HEAD user/two-factor-recovery-codes ............. two-factor.recovery-codes › Laravel\Fortify › RecoveryCodeController@index
POST user/two-factor-recovery-codes .. two-factor.regenerate-recovery-codes › Laravel\Fortify › RecoveryCodeController@store
GET|HEAD user/two-factor-secret-key ................ two-factor.secret-key › Laravel\Fortify › TwoFactorSecretKeyController@show
GET|HEAD user/confirmed-password-status ....... password.confirmation › Laravel\Fortify › ConfirmedPasswordStatusController@show
vendor/laravel/fortify/src/Http/Controllers/ConfirmedPasswordStatusController.php
ここのshow()メソッドです。処理内容としては、最後のパスワード確認からの経過時間を見て、再入力が必要かを判定するAPIだそうです。
Enable 2FAをクリックした後の処理の流れ
Enable 2FAをクリックした後の処理の流れ
Frontend
resources/js/pages/settings/TwoFactor.vue v-bind="enable.form()"
resources/js/routes/two-factor/index.ts enable.form = enableForm
enable.definition = {
methods: ["post"],
url: '/user/two-factor-authentication',
} satisfies RouteDefinition<["post"]>
Backend
vendor/laravel/fortify/routes/routes.php [TwoFactorAuthenticationController::class, 'store']
vendor/laravel/fortify/src/Http/Controllers/TwoFactorAuthenticationController.php store
return app(TwoFactorEnabledResponse::class)
Frontend
@success="showSetupModal = true" 発火
<TwoFactorSetupModal
v-model:isOpen="showSetupModal"
:requiresConfirmation="requiresConfirmation"
:twoFactorEnabled="twoFactorEnabled"
/>
resources/js/components/TwoFactorSetupModal.vue
qrCodeSvg で描画されている模様
resources/js/composables/useTwoFactorAuth.ts qrCode.url()
resources/js/routes/two-factor/index.ts
qrCode.definition = {
methods: ["get","head"],
url: '/user/two-factor-qr-code',
} satisfies RouteDefinition<["get","head"]>
このgetメソッドでQRコードを取得していると思われる。
途中経過
処理を追うことで、設計を学ぶことができるのは良し。
ただ膨大な脳のリソースを食うため、休止します。














