Laravel Sail React やろうとしたらまだダメFortify2

パクリ41発目!!
疲れてきた

パクリ元

内容

Laravel Fortify部分、前回で直した気がするのでJS側もきれいな状態に持っていくことにする。でもよく考えたら2要素認証でのメール認証チェックは不要だったな、だってログイン時にチェックするもんね、

Fortify 一応始めから確認

ユーザー登録して、メール認証せずにログインしてもエラー表示。OK。

その後受信メールのリンク押下!エラー!!

前 Sanctum 呼び出し時の await が足りなかった場合と同じ。別タブでログインやったからだな、運用時は APP_DEBUG=false にすればこんな画面は出ないし、別の流れを作ったユーザーが原因だから問題ないが、一応登録後に遷移する画面にパクリ元1つ目同様の再送信ボタンを置いておく。画面間のパラメータの受け渡しをパクリ元2つ目同様にしてして再度試す。

おー、、この機能はログインしていないといけないのか、、うすうすは気づいていたけど途中で始めたからには止めることもできず行ってまぇとなってたけど、、

メール認証なしでログイン許すんだな、Fortifyよ

メール認証なくて気持ち悪い人はクライアント側で制御しておいてね、という主義なんだな、言ってくれよ早めにさ、、だからメール認証ない場合にログインできないなんてことはどこにも書いてないんだよな。。

もういい!全部戻す!時間がかかったがやっと理解できた。人生こういうもんだ。AI でやればこんな目に合わない?いやいいんだ、AI への聞き方が分からないんじゃないぞ、正解に直接たどり着くだけが人生じゃないんだ!今までの成功体験てのは何年もの失敗がうんだモノってのが死ぬほどあるんだよ!そんなの AI が教えてくれるかよ!!はぁ、時間がもったいなかった、、クッソー

まずは、メール送信しました画面はパスワードリセットでも使っているので、登録画面後の場合だけ認証メール再送信ボタンを出すように修正しておく。

resouces/ts/features/auth/Register.tsx
・・・
            navigate("/sent_email", {state: {before: "register"}});
・・・
resouces/ts/features/auth/SentEmail.tsx
・・・
import { useLocation } from "react-router-dom";
import { sendRegisterEmail } from '../../infrastructures/api/authApi';
・・・
export const SentEmail = () => {
    const location = useLocation()
    const before = location.state?.before;
    const onClickSend = async () => {
        try {
             await sendRegisterEmail();
             toast.success("メールを再送しました。");
         } catch (e) {
             console.log(e)
         }
     };
・・・
                <CardContent>
                    <div>指定したメールアドレスにメールを送信しました。</div>
                    <div>受信したメールを確認してください。</div>
                </CardContent>

                {before === 'register' &&
                <CardActions>
                    <Button
                        variant="contained"
                        size="large"
                        color="primary"
                        onClick={onClickSend}
                    >
                    メール再送
                    </Button>
                </CardActions>
                }
・・・
resouces/ts/infrastructures/api/authApi.ts
・・・
export const sendRegisterEmail = () => {
    return axiosClient.post('/api/email/verification-notification');
};

認証のために作ったファイルを思い切り消す。

~/example-app$ rm app/Actions/Fortify/RedirectIfTwoFactorAuthenticatable.php 
~/example-app$ rm app/Http/Middleware/RedirectIfAuthenticated.php 

認証のために追記した箇所を戻す。このカスタム認証はブラックリストに載ってるやつをログインさせないとかに応用すればいいだろう、ポジティブに。

bootstrap/app.php
・・・
->withMiddleware(function (Middleware $middleware) {
        $middleware->statefulApi();
-       $middleware->alias([
-           'guest' => App\Http\Middleware\RedirectIfAuthenticated::class
-       ]);
    })
・・・
app/Providers/FortifyServiceProvider
・・・
-use Illuminate\Support\Facades\Auth;
-use Laravel\Fortify\Contracts\LoginResponse;
-use Laravel\Fortify\Contracts\LogoutResponse;
-
-use Laravel\Fortify\Actions\AttemptToAuthenticate;
-use Laravel\Fortify\Actions\CanonicalizeUsername;
-use Laravel\Fortify\Actions\EnsureLoginIsNotThrottled;
-use Laravel\Fortify\Actions\PrepareAuthenticatedSession;
-use App\Actions\Fortify\RedirectIfTwoFactorAuthenticatable;
-use Laravel\Fortify\Features;
・・・
    public function register(): void
    {
-       $this->app->instance(LoginResponse::class, new class implements LoginResponse
-       {
-           public function toResponse($request)
-           {
-               $email_verified_at = Auth::user()->email_verified_at;
-               if (!isset($email_verified_at)) {
-                   Auth::logout();
-
-                   $request->session()->invalidate();
-                   $request->session()->regenerateToken();
-
-                   abort(403, 'Your email address is not verified.');
-              }
-
-               return response()->json(['two_factor' => false]);
-           }
-       });
-
-       $this->app->instance(LogoutResponse::class, new class implements LogoutResponse
-       {
-           public function toResponse($request)
-           {
-               return response()->json([
-                   'code' => 200,
-                   'user' => $request->user(),
-               ]);
-           }
-       });
    }
・・・
    public function boot(): void
    {
・・・
-       Fortify::authenticateThrough(function (Request $request) {
-           return array_filter([
-                   config('fortify.limiters.login') ? null : EnsureLoginIsNotThrottled::class,
-                   config('fortify.lowercase_usernames') ? CanonicalizeUsername::class : null,
-                   Features::enabled(Features::twoFactorAuthentication()) ? RedirectIfTwoFactorAuthenticatable::class : null,
-                   AttemptToAuthenticate::class,
-                   PrepareAuthenticatedSession::class,
-           ]);
-       });
    }

これで一切合切きり戻した。これから react 側で実装予定だった、ログインせずに URL 直接入力でログイン画面強制表示処理に加え、ログインしててもメール認証ない場合はメール認証しろ画面強制表示処理を追加することになるだろう。

雑感

結局ここ最近やってた箇所全部戻った。