AIノーコードやLow-Codeで生成したモバイルアプリでFirebaseのJWTエラーを回避する近道は、トークンの扱いを二つの原則に沿わせることです。第一に、クライアントは毎回のリクエストで新しいIDトークンを取得すること。第二に、バックエンドは受け取ったトークンを必ずAdmin SDKで検証してから信頼すること。Firebaseが発行するIDトークンはJWTであり、有効期限は1時間で自動的に更新されます。AI生成コードはこの更新や検証を省いてしまうことが多く、それが期限切れや引数エラーの主な原因になります。まずこの二つを直せば、よく見るエラーの大半は消えます。
簡単な回答
FirebaseのIDトークンはJWTで、正しい形式で、期限切れでなく、正しく署名されていればサーバーで検証できます。検証はAdmin SDKの verifyIdToken で行うのが正式な方法で、Firebase公式ドキュメントがそう定めています。エラーを回避する要点は、クライアントで getIdToken を使って常に新しいトークンを送り、バックエンドで必ず検証し、期限切れなら更新して再試行することです。
FirebaseのJWTエラーとは何か
FirebaseのJWTエラーは、Firebase Authenticationが発行するIDトークンをアプリが正しく扱えていないときに出ます。ユーザーがサインインすると、Firebaseはそのユーザーを表すIDトークンを発行します。これは署名付きのJWTで、誰がサインインしているかを示す情報と有効期限を含みます。このトークンをバックエンドに送り、バックエンドが本人確認の根拠として使うのが基本の流れです。
エラーはこの流れのどこかがずれたときに現れます。代表的なものは、期限切れを示す auth/id-token-expired、失効を示す auth/id-token-revoked、検証に誤った値を渡したことを示す auth/argument-error です。いずれも「トークンが信頼できない」という同じ結論に至りますが、原因は異なります。だからエラーコードを読み分けることが、直し方を選ぶ第一歩になります。
なぜAI生成アプリで起きやすいのか
AIノーコードやLow-Codeのツールは動くコードを素早く出しますが、トークンのライフサイクルを正しく組み込めないことがよくあります。IDトークンの有効期限は1時間で、Firebaseのクライアントライブラリは通常これを自動で更新します。ところが生成されたコードが古いトークンを変数に保存して使い回すと、1時間後には期限切れになり、auth/id-token-expired が発生します。これは最も多いパターンです。
もう一つ多いのが、検証関数に渡す値の取り違えです。verifyIdToken に渡すべきなのはIDトークンなのに、生成コードがFirebaseのWeb APIキーやカスタムトークン、あるいは別の文字列を渡してしまうと auth/argument-error になります。さらに、AI生成のバックエンドはサーバー側の検証そのものを省き、クライアントが送ってきた情報をそのまま信じてしまうこともあります。この場合エラーは出ませんが、もっと深刻な問題、つまり検証されていない主張を信頼するという穴が残ります。
まず確認して直すこと
最初にやるべきは、クライアントが送るトークンが常に新しいことを保証することです。生成コードがトークンを一度取得して保存しているなら、リクエストごとに getIdToken を呼んで最新のトークンを取得するように変えます。強制的に更新したいときは getIdToken に true を渡します。こうすれば、SDKが期限を管理し、期限切れのトークンを送ってしまう事故がなくなります。
次に、バックエンドで verifyIdToken を使って必ず検証することです。この関数はトークンの形式、有効期限、署名、発行者と対象者を確認し、正しければ復号したトークンを返します。auth/argument-error が出るなら、渡している値が本当にIDトークンかを確かめます。ログイン状態やユーザーIDだけをクライアントから受け取って信じるのではなく、トークンを検証してから、その中の情報を使うようにします。
フロントエンドとバックエンドの境界
このテーマの核心は、フロントエンドとバックエンドの境界にあります。IDトークンを取得するのはクライアントの役割ですが、それを信頼してよいかを判断するのはバックエンドの役割です。AI生成アプリの弱点は、この境界を曖昧にして、クライアントが「自分はこのユーザーだ」と言った内容を検証なしで受け入れてしまう点にあります。攻撃者はクライアントを自由に操作できるため、検証のない主張は根拠になりません。
正しい形は、クライアントが毎回のリクエストにIDトークンを付け、バックエンドがそれを verifyIdToken で検証し、検証に通ったトークンの中身だけを使う、という流れです。ここで大切なのは秘密の置き場所です。Firebaseの設定やWeb APIキーは公開されて当然の情報で、クライアントに入っていても問題ありません。一方、Admin SDKが使うサービスアカウントの秘密鍵は本物の秘密であり、サーバーだけに置き、決してアプリに埋め込んではいけません。
エラーコード対応表
よく出るエラーを原因と対処で並べると、直し方が選びやすくなります。次の表にまとめます。
| エラー | 主な原因 | 対処 |
|---|---|---|
| auth/id-token-expired | トークンの期限切れ(1時間) | getIdToken で更新して再送信 |
| auth/id-token-revoked | トークンが失効している | 再ログインさせて再取得 |
| auth/argument-error | 検証に誤った値を渡した | 正しいIDトークンを渡す |
| auth/invalid-id-token | トークンが不正または改ざん | 発行し直して検証する |
| 検証の欠落 | サーバー側検証をしていない | Admin SDKで検証する |
一番上の行が最頻出です。多くの場合、トークンを更新して送り直すだけで解決します。
回避チェックリスト
公開前に、トークンの扱いが原則どおりかを確認しておくと安心です。下のチェックリストが要点を押さえます。
| 確認項目 | 対応 | 完了 |
|---|---|---|
| トークンの自動更新 | getIdToken で毎回新しいトークンを取得 | [ ] |
| サーバー側検証 | Admin SDKの verifyIdToken で検証 | [ ] |
| 秘密鍵の分離 | サービスアカウント鍵をクライアントに入れない | [ ] |
| 公開設定の理解 | Web APIキーは公開情報と理解する | [ ] |
| 期限切れの処理 | 期限切れなら更新して再試行 | [ ] |
| 時刻の同期 | 端末とサーバーの時刻ずれを確認 | [ ] |
見落とされがちなのは二番目です。サーバー側の検証を省くとエラーは消えても、検証されていない主張を信じる穴が残ります。
セキュリティスキャンの位置づけ
トークンの流れを正すのは実装の作業ですが、完成したアプリに秘密が漏れていないかを確かめるのは別の検証で、そこでスキャンが役立ちます。
PTKD.comのようなスキャナーは、AndroidやiOSのアプリのパッケージを解析し、サーバーに置くべき秘密、たとえばサービスアカウントの秘密鍵やAPIの秘密キーがクライアントに埋め込まれていないかを調べ、結果をOWASP MASVSに対応づけます。境界をはっきりさせると、Firebaseの公開設定やWeb APIキーがアプリに含まれていること自体は問題ではありません。スキャナーが探すのはその逆、つまり公開側に漏れてしまった本物の秘密です。だから公開前のスキャンは、埋め込むべきでない鍵が混ざっていないかを確認する良い機会になります。
まとめ
- FirebaseのIDトークンはJWTで、有効期限は1時間、SDKが自動で更新します。古いトークンを使い回すと auth/id-token-expired が出ます。
- verifyIdToken に渡すのはIDトークンです。Web APIキーやカスタムトークンなど別の値を渡すと auth/argument-error になります。
- エラー回避の要点は二つ、クライアントで毎回 getIdToken を使って新しいトークンを送ること、バックエンドで必ず検証してから信頼することです。
- フロントとバックの境界を守り、検証されていないクライアントの主張は信頼しないこと。Web APIキーは公開情報、サービスアカウントの秘密鍵はサーバー専用です。
- 公開前にPTKD.comのようなツールでスキャンし、埋め込むべきでない秘密鍵がクライアントに混ざっていないかを確認します。



