Firexport部落格

Firebase App Check 錯誤排解:403、App attestation failed、無效權杖

App Check 錯誤出在兩個步驟之一:應用程式透過認證供應商(Play Integrity、App Attest、reCAPTCHA)取得權杖的步驟,或 Firebase 服務驗證該權杖的步驟。前一步失敗,後一步也會失敗,所以不要只看服務的錯誤,請先找出權杖交換的錯誤,再修正各平台的註冊值。Android 模擬器、iOS 模擬器和 localhost 本來就無法通過認證,所以要使用偵錯權杖。

重點整理

  • 先找出失敗的步驟。權杖交換以 403 結束,是供應商的設定問題;沒有交換錯誤、只有服務拒絕要求,則是權杖缺少或無效。從訊息區分
  • 開發環境使用偵錯權杖。Android 模擬器、iOS 模擬器、localhost 和偵錯簽署的版本,都無法通過實際的認證。註冊方法
  • 每個平台都有必須相符的值。Android 是簽署憑證的 SHA-256,Apple 是 Team ID 和 App Attest 的 production 環境,Web 是 reCAPTCHA 金鑰的網域。各平台的原因
  • AI Logic 自 2026 年 11 月 2 日起自動強制執行 App Check。最晚只能延到 2027 年 1 月 21 日。該怎麼做

從訊息找出失敗的步驟

訊息失敗的步驟
Android:Error returned from API. code: 403 body: App attestation failed.取得權杖。App Check 伺服器沒有接受 Play Integrity 的結果。
Apple:The server responded with an error … HTTP status code: 403取得權杖。App Attest 或 DeviceCheck 的結果沒有被接受。
Web:HTTP status: 403. (appCheck/fetch-status-error),接著是 appCheck/throttled取得權杖。reCAPTCHA 的結果沒有被接受,SDK 在 24 小時內不會重試。
Cloud Storage:Firebase App Check token is invalid.(Web SDK 中為 storage/unauthorized-app)使用權杖。權杖缺少或無效。
可呼叫函式(callable):functions/unauthenticated使用權杖。設定了 enforceAppCheck: true 的函式拒絕了要求。Auth 權杖有誤時傳回的也是這個代碼,要靠函式記錄中的 AppCheck token was rejected 來區分。
Realtime Database:Provided AppCheck credentials for the app named ... are invalid使用權杖。權杖無效。
Firebase AI Logic:403 PERMISSION_DENIED: ... you must enforce Firebase App Check.使用權杖。請參閱 AI Logic 一節。

沒有取得權杖時,服務要求中就沒有有效的權杖(Web SDK 會附上預留位置權杖送出)。所以即使看到的是服務傳回的錯誤,也請先確認是否同時記錄了取得權杖的錯誤。失敗之後,SDK 會延後重試。Web 在 403、404 之後為 24 小時,Android 和 Apple 在 400、404 之後為 24 小時,其他錯誤最多 4 小時。這個狀態只存在記憶體中,所以修正設定後,請重新啟動應用程式或重新整理網頁再確認。

開發時使用偵錯權杖

Android 模擬器和 iOS 模擬器都不算有效裝置,沒有在 Google Play 上架的偵錯版本也無法通過 Play Integrity。原則上不應將 localhost 加入 reCAPTCHA 金鑰。在這些環境中,請啟用偵錯供應商,並將記錄中輸出的權杖註冊到控制台。

  1. 只在開發版本中啟用偵錯供應商。
    // Android (Kotlin): com.google.firebase:firebase-appcheck-debug
    Firebase.appCheck.installAppCheckProviderFactory(
        if (BuildConfig.DEBUG) DebugAppCheckProviderFactory.getInstance()
        else PlayIntegrityAppCheckProviderFactory.getInstance(),
    )
    
    // iOS (Swift): before FirebaseApp.configure()
    #if DEBUG
    AppCheck.setAppCheckProviderFactory(AppCheckDebugProviderFactory())
    #endif
    
    // Web: before initializeAppCheck(), in development builds only
    self.FIREBASE_APPCHECK_DEBUG_TOKEN = true;
    
    // Flutter (firebase_app_check 0.5+)
    await FirebaseAppCheck.instance.activate(
      providerAndroid: kDebugMode
          ? const AndroidDebugProvider()
          : const AndroidPlayIntegrityProvider(),
      providerApple: kDebugMode
          ? const AppleDebugProvider()
          : const AppleAppAttestWithDeviceCheckFallbackProvider(),
    );
  2. 執行應用程式,在記錄中找出 debug token。新版 SDK 會以 Firebase App Check debug token: <UUID> 的格式輸出(Android 在 logcat,Apple 在 Xcode 主控台,Web 在瀏覽器主控台)。
  3. 註冊權杖。在 Firebase 控制台的 App Check 中開啟應用程式(Apps)分頁,從應用程式的 ⋮ 選單選取管理偵錯權杖(Manage debug tokens)。每個應用程式最多可註冊 20 個。
  • 權杖會改變。Android 清除應用程式資料或重新安裝、Apple 重新安裝、Web 改用其他瀏覽器設定檔或清除網站資料後,都會產生新的權杖。新的權杖必須重新註冊。
  • 在 CI 中傳入已註冊的權杖。Web 將權杖字串指定給 self.FIREBASE_APPCHECK_DEBUG_TOKEN,Android 使用檢測設備測試引數 firebaseAppCheckDebugSecret,Apple 使用 scheme 環境變數 AppCheckDebugToken,Flutter 使用 debugToken 參數。
  • 像對待密碼一樣對待權杖。不要提交到存放區,也不要將偵錯供應商和權杖放進正式版本。

各平台的原因

Android(Play Integrity)

症狀原因解決方法
只在模擬器或偵錯版本上失敗模擬器不是有效裝置,Google Play 也不認得偵錯簽署。偵錯權杖
從 Play 安裝的應用程式失敗註冊的是上傳金鑰的 SHA-256。使用 Play 應用程式簽署時,Google 會用應用程式簽署金鑰重新簽署。在 Play Console 中點選前往 Play 應用程式簽署(Manage Play app signing),將該頁面上應用程式簽署金鑰憑證的 SHA-256 註冊到 App Check
在 Play 以外發布的應用程式失敗預設設定只放行 Google Play 認得的應用程式版本(PLAY_RECOGNIZED)。在 App Check 的 Play Integrity 設定中,將 PLAY_RECOGNIZED 改為非必要(Not required),並將最低裝置完整性等級提高到裝置完整性(Device integrity)
使用者變多後失敗(TOO_MANY_REQUESTS,-8)未連結 Play Console 的 Cloud 專案,Play Integrity 要求每天限 1 萬次。在 Play Console 的 Play Integrity API 項目中,透過連結雲端專案(Link Cloud project)連結 Firebase 專案,需要時再申請提高配額。只有 Google Play 上的應用程式才能連結。

Apple(App Attest、DeviceCheck)

症狀原因解決方法
在模擬器上失敗模擬器不是有效裝置。偵錯權杖
只有從 Xcode 安裝的版本失敗新增 App Attest capability 後,環境會設為 development,而 App Check 不接受這個環境的結果。TestFlight 和 App Store 的版本一律是 production。將 entitlements 檔案中的 App Attest Environment 設為 production
所有裝置上都失敗在 Firebase 註冊的 Team ID 與應用程式的不一致。在 Firebase 專案設定的 Apple 應用程式中輸入正確的 Team ID
在 Mac 或 App 延伸功能中失敗這些環境不支援 App Attest。加入 DeviceCheck 做為備援供應商。DeviceCheck 需要將在 Apple 開發人員網站建立的私密金鑰(.p8)及其金鑰 ID 註冊到 App Check
Flutter:選擇的供應商在實體裝置上沒有被使用如果先在 AppDelegate 中呼叫 FirebaseApp.configure(),providerApple 就會被忽略。刪除 AppDelegate 中的 configure(),只使用 Dart 中的 Firebase.initializeApp()

Web(reCAPTCHA)

症狀原因解決方法
只在已部署的網站上失敗該網域不在 reCAPTCHA 金鑰的網域清單中。在金鑰設定中新增網域。最多需要 30 分鐘才會生效
在 localhost 上失敗正式環境用的金鑰不會加入 localhost。偵錯權杖
更換金鑰後失敗供應商類別與在 Firebase 註冊的值不相符。Enterprise 金鑰在程式碼中用 ReCaptchaEnterpriseProvider,在 Firebase 中填網站金鑰。v3 金鑰在程式碼中用 ReCaptchaV3Provider,在 Firebase 中填密鑰
修正後仍然失敗403、404 之後,SDK 在 24 小時內不會重試權杖交換。重新整理網頁。這個狀態只存在記憶體中。

AI Logic:自 2026 年 11 月 2 日起自動強制執行

自 2026 年 11 月 2 日起,Firebase 會為尚未強制執行 App Check 的專案,自動對 Firebase AI Logic 強制執行 App Check。沒有有效權杖的要求會遭到封鎖,未整合 App Check 就已發布的應用程式版本也一樣。提到 App Check 的 AI Logic 錯誤有兩種。

403 PERMISSION_DENIED: To access this model, you must enforce
Firebase App Check.

403 PERMISSION_DENIED: Firebase AI Logic has been deactivated in this
project. To resume using Firebase AI Logic, you must enforce Firebase
App Check.
  • 第一種是在沒有有效 App Check 權杖的情況下,呼叫了常遭濫用的模型。請設定並強制執行 App Check。開發時使用偵錯供應商。
  • 第二種是專案被判定為閒置,而且沒有強制執行 App Check。如果已經在強制執行卻仍出現這個錯誤,請檢查重播保護(replay protection)。開啟時(包括 Monitor only 模式)只接受有限用途權杖(limited-use token)。

如果沒有 App Check 的版本仍在使用者手中,可以延後強制執行。在 App Check 的 API(APIs)分頁中修改 Firebase AI Logic 那一列的 Enforces 日期即可,最晚為 2027 年 1 月 21 日。如果已經處於已強制執行(Enforced)狀態,修改日期後,還要在該列的設定(Set up)中將基本保護(Baseline protection)改為 Unenforced (monitoring only),將重播保護改為 Disabled,才能解除。Google 不建議這麼做,請在那之前發布已整合 App Check 的版本。

對其他服務強制執行之前

  • 先看指標。App Check 的 API(APIs)分頁會依服務將要求分為已驗證(Verified)、過時的用戶端(Outdated client,沒有權杖)、來源不明(Unknown origin)和無效(Invalid)。強制執行後只有已驗證的要求能通過,所以請在近期要求幾乎都已驗證時再強制執行。
  • 舊版應用程式會遭到封鎖。沒有 App Check SDK 的版本,從強制執行的那一刻起,要求就會遭到拒絕。
  • 最多需要 15 分鐘才會生效。不要一啟用強制執行就判斷結果。
  • Cloud Functions 只能對可呼叫函式強制執行。加上 enforceAppCheck: true 並重新部署後才會生效。onRequest 函式不在 App Check 強制執行的範圍內,必須用 Admin SDK 自行驗證權杖。

資料來源

所有文章 →