見出し画像

【AI時代の個人開発】5. 長時間利用でもログインが切れない仕組みを作った話

AIを使い側から、使いこなす側へ。

2026年7月2日更新
シリーズを書き進める中で得た気づきを反映し、リード文・構成・文章表現を見直しました。


前々回のシリーズ3では、Firebase Authenticationを採用し、ログイン機能をゼロから自作する「ログイン地獄」を回避した話を書きました。

メールアドレスとパスワードでログインでき、一度認証すればブラウザを閉じた後もログイン状態が維持される。ここまで整えば、ログイン機能は完成したように見えます。

ところが、開発を進める中で一つの疑問が残りました。

朝にログインしたまま、夕方まで画面を開いていたらどうなるのか。

画面上ではログイン状態が続いていても、裏側でAPIを使うための認証情報には有効期限があります。

今回は、長時間利用でも操作が途切れにくい仕組みと、公開後の問い合わせを減らすために考えた設計の話です。



ログイン状態が続いても、認証情報は更新される

Firebase Authenticationを導入すると、サービスへアクセスするたびにメールアドレスとパスワードを入力せずに済みます。

ただし、画面上のログイン状態と、APIを呼び出す際に使う認証情報は、別の仕組みで動いています。

ログイン後に予約枠を登録したり変更したりすると、ブラウザからサーバーへAPIリクエストが送られます。その際、サーバー側では「ログイン済みのユーザーから届いたリクエストか」を確認します。

そこで使われるのが、Firebase AuthenticationのIDトークンです。

IDトークンは、ログイン済みであることを証明する「会員証」のような役割を持ちます。ブラウザはAPIリクエストと一緒にIDトークンを送り、サーバー側は形式・有効期限・署名などを検証します。


IDトークンには有効期限がある

Firebase AuthenticationのIDトークンは、発行から1時間で期限切れになります。

トークンが外部へ漏れた場合のリスクを長く残さないため、短い有効期限を設け、新しいものへ差し替える仕組みです。

ただし、1時間ごとに再ログインを求められるわけではありません。

Firebase Authenticationでは、IDトークンとあわせてRefreshトークンも発行されます。Refreshトークンを使うことで、ログイン状態を保ったまま新しいIDトークンを取得できます。

IDトークンとRefreshトークンの役割

会員証にあたるIDトークンには短い有効期限があり、Refreshトークンが新しい会員証への差し替えを支えます。

では、この更新処理をアプリ側でどこまで作り込むべきなのか。

そこが次の論点でした。


通常時の更新は Firebase SDKに任せる

IDトークンの有効期限が1時間なら、1時間ごとに更新するタイマーを自分で作る。

当初は、そのような処理も必要になるのではないかと考えました。

実際には、Firebase SDKが更新の要否を判断してくれます。APIを呼び出す直前に、次の処理を実行します。

const token = await currentUser.getIdToken();

getIdToken()は、現在のIDトークンが十分に有効であれば、そのトークンを返します。期限切れになっている場合や、有効期限まで残り5分を切っている場合は、新しいIDトークンを取得します。

アプリ側で有効期限を細かく管理するより、APIリクエストの直前にgetIdToken()を呼び出し、その時点で使えるトークンを受け取る。

この設計によって、自前の更新処理を増やさずに済みました。

Firebase SDKに任せる部分と、自分で設計する部分を切り分ける。

Firebase Authenticationを採用する価値は、ログイン画面を簡単に作れることだけではありません。ログイン後の状態管理も、標準機能を理解して使うことで複雑さを抑えられます。


認証エラーが起きたときだけ、強制更新して再送する

通常時は、APIリクエストの直前にgetIdToken()を実行します。

それでも認証エラーが返ってきた場合に備え、次の復旧手順を用意しました。

  1. 通常どおりIDトークンを取得する

  2. APIリクエストを送信する

  3. 401 Unauthorizedが返った場合、IDトークンを強制更新する

  4. 新しいIDトークンでAPIを1回だけ再送する

  5. 再び失敗した場合は、再ログインを案内する

強制更新に使う処理は、次のとおりです。

const token = await currentUser.getIdToken(true);

引数にtrueを渡すと、現在のIDトークンの有効期限に関係なく、新しいIDトークンを取得します。

APIリクエストのフロー図

APIリクエストのフロー図

トークンの強制更新を毎回呼ばない

APIを呼ぶたびにgetIdToken(true)を実行すれば、常に新しいトークンを使えます。

ただし、有効なIDトークンが残っている場合にも強制更新が走ります。通常時は引数なしのgetIdToken()を使い、更新の判断をFirebase SDKに任せる方針にしました。

状態管理の考え方まとめ

通常時はSDKへ任せ、認証エラーが返ったときだけ強制更新する。

この役割分担が、処理を増やしすぎずに復旧手段を持つための軸になりました。

401 と 403 は分けて考える

APIのエラー処理を設計する際には、401と403を分けて考える必要があります。

HTTPステータスコードの意味

401は、認証情報が不足している、無効になっている、期限切れになっている場合などに返されます。新しいIDトークンで再送すれば、復旧できる可能性があります。

一方の403は、認証後の権限に関するエラーです。トークンを更新しても権限は変わらないため、自動再送ではなく、状況に応じたメッセージを表示します。

エラーの種類を分けることで、復旧を試す場面と、処理を止める場面が明確になりました。

自動リトライは1回に制限する

強制更新後の再送は、1回だけに制限します。

上限を設けずに繰り返すと、無限ループや不要な通信につながり、画面操作にも影響が出ます。障害が起きた際には、本来の原因とは別のログや通信が増え、調査もしにくくなります。

復旧できる可能性がある処理を1回だけ試し、再び失敗した場合は再ログインを案内する。

失敗したときの止め方まで決めることで、認証エラーが別の問題へ広がることを防ぎました。


見えない修正が、将来の問い合わせを減らす

IDトークンの更新処理は、画面からは見えません。正常に動いている間、その存在を意識する場面もほとんどありません。

だからこそ、考慮が漏れたまま公開すると、原因の分かりにくい問い合わせにつながります。

  • 画面は開いたままなのに、急に保存できなくなった

  • 予約枠を登録しようとしたらエラーになった

  • ページを再読み込みしたら直った

  • ログアウトした覚えがないのに操作できなくなった

こうした問題は、発生頻度が低いほど調査が難しくなります。

操作手順、ログインした時間、画面を開いていた時間、通信状態。複数の条件が重なったときだけ起きる不具合は、公開後に再現するだけでも時間がかかります。

認証エラーから自動で復旧できる範囲を決め、復旧できない場合の案内まで用意しておく。

派手な新機能ではありませんが、公開後の困りごとを設計段階で減らすための対策になりました。


AIとの対話で「動けばよい」から一歩踏み込めた

今回のきっかけは、Firebase Authenticationの認証回数について調べていたことでした。

ログイン状態を保つために、何度もログイン処理が行われているのではないか。長時間使い続けた場合、途中で操作できなくなる可能性はないか。

最初は、そのような素朴な疑問でした。

AIとの対話を重ねる中で、「ログイン」「ログイン状態の維持」「IDトークンの更新」「APIエラーからの復旧」が別の論点として見えてきました。

一つの疑問を分解し、それぞれに必要な処理を整理する。

その結果、通常時はFirebase SDKへ任せ、認証エラーが起きたときだけ強制更新し、再送は1回で止めるという設計にたどり着きました。

AIとの対話によって増えたのは、コードだけではありません。

何を仕組みに任せ、どこから自分で判断するのか。

その境界を考えることで、「動くもの」から「壊れにくいもの」へ一歩進めたように感じています。


まとめ:ログイン後まで考えて、認証機能は完成する

今回の設計は、次のように整理できます。

  • 通常時はgetIdToken()を使い、更新の判断をFirebase SDKに任せる

  • 401が返った場合だけ、getIdToken(true)で強制更新する

  • 強制更新後のAPI再送は1回に制限する

  • 403では自動再送を行わず、状況に応じた案内を表示する

  • 正常時の処理だけでなく、失敗時の止め方まで決めておく

ログイン画面を作り、ログイン状態を維持できるようにすれば、サービスはひとまず動きます。

ただ、長時間利用や一時的な認証エラーまで考えると、ログイン後の設計も欠かせませんでした。

表面から見えない部分を先回りして整えることで、操作する側は認証の仕組みを意識せずに使えます。運営側でも、原因の分かりにくい問い合わせや調査に追われる可能性を抑えられます。

ログイン機能の完成は、ログインできた瞬間ではなく、その後も安心して使い続けられる状態まで含まれる。

今回の実装を通じて、そう捉えるようになりました。


次回は、
6. AI時代でも、Pull Requestは最後の防波堤だった話
について書きます。

AIコーディングで開発速度は大きく上がりました。

しかし、速く作れることと、安心して反映できることは別の話です。

AIに任せる部分と、人間が最後に確認する部分。

シリーズ全体を通して重要な、その境界線について考えます。


関連情報

次回:シリーズ6


本記事内の表について

トークンの違いなどをわかりやすく表現するために「表」を使用しました。この表は、まるしょーさんのChrome拡張機能を使用しています。


前回:シリーズ4

【AI時代の個人開発】シリーズを最初から読む


創作大賞2026の選考期間中は、創作大賞2026 ビジネス部門 応募作品|AI時代の個人開発 にも全10話をまとめています。

いいなと思ったら応援しよう!

油川 流樹🥝個人開発🍇 いただいたお気持ちは執筆用のチョコ代に当てさせていただきます!