iOS 上的 Firebase AppCheck:403 权限错误 - PERMISSION_DENIED

问题描述 投票:0回答:4

问: 如何解决 Firebase App Check 的权限错误?

背景: 我已根据文档启用了 App Check:

DeviceCheck 已启用/配置如下: https://firebase.google.com/docs/app-check/ios/devicecheck-provider

应用程序证明已启用,配置如下: https://firebase.google.com/docs/app-check/ios/devicecheck-provider

SDK已添加到项目中,代码来自: https://github.com/firebase/firebase-ios-sdk/blob/master/FirebaseAppCheck/Apps/FIRAppCheckTestApp/FIRAppCheckTestApp/AppDelegate.swift

具体来说,在appdelegate中: 代币设置:

FirebaseApp.configure()

requestDeviceCheckToken()

requestDebugToken()

if #available(iOS 14.0, *) {
  requestAppAttestToken()
}

打电话:

  // MARK: App Check providers
  func requestDeviceCheckToken() {
    guard let firebaseApp = FirebaseApp.app() else {
      return
    }

    DeviceCheckProvider(app: firebaseApp)?.getToken { token, error in
      if let token = token {
        print("DeviceCheck token: \(token.token), expiration date: \(token.expirationDate)")
      }

      if let error = error {
        print("DeviceCheck error: \((error as NSError).userInfo)")
      }
    }
  }

  func requestDebugToken() {
    guard let firebaseApp = FirebaseApp.app() else {
      return
    }

    if let debugProvider = AppCheckDebugProvider(app: firebaseApp) {
      print("Debug token: \(debugProvider.currentDebugToken())")

      debugProvider.getToken { token, error in
        if let token = token {
          print("Debug FAC token: \(token.token), expiration date: \(token.expirationDate)")
        }

        if let error = error {
          print("Debug error: \(error)")
        }
      }
    }
  }

  @available(iOS 14.0, *)
  func requestAppAttestToken() {
    guard let firebaseApp = FirebaseApp.app() else {
      return
    }

    guard let appAttestProvider = AppAttestProvider(app: firebaseApp) else {
      print("Failed to instantiate AppAttestProvider")
      return
    }

    appAttestProvider.getToken { token, error in
      if let token = token {
        print("App Attest FAC token: \(token.token), expiration date: \(token.expirationDate)")
      }

      if let error = error {
        print("App Attest error: \(error)")
      }
    }
  }

requestDeviceCheckToken()返回权限错误:

DeviceCheck error: ["NSLocalizedFailureReason": The server responded with an error: 
 - URL: https://firebaseappcheck.googleapis.com/v1beta/projects/<GOOGLE_APP_ID>:exchangeDeviceCheckToken 
 - HTTP status code: 403 
 - Response body: {
  "error": {
    "code": 403,
    "message": "Requests from this iOS client application \u003cempty\u003e are blocked.",
    "status": "PERMISSION_DENIED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "API_KEY_IOS_APP_BLOCKED",
        "domain": "googleapis.com",
        "metadata": {
          "service": "firebaseappcheck.googleapis.com",
          "consumer": "projects/<my project #>"
        }
      }
    ]
  }
}

requestDebugToken() 返回权限错误:

Debug error: Error Domain=com.firebase.appCheck Code=0 "The server responded with an error: 
 - URL: https://firebaseappcheck.googleapis.com/v1beta/projects/<GOOGLE_APP_ID>:exchangeDebugToken 
 - HTTP status code: 403 
 - Response body: {
  "error": {
    "code": 403,
    "message": "Requests from this iOS client application \u003cempty\u003e are blocked.",
    "status": "PERMISSION_DENIED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "API_KEY_IOS_APP_BLOCKED",
        "domain": "googleapis.com",
        "metadata": {
          "consumer": "projects/<my project #>",
          "service": "firebaseappcheck.googleapis.com"
        }
      }
    ]
  }
}
" UserInfo={NSLocalizedFailureReason=The server responded with an error: 
 - URL: https://firebaseappcheck.googleapis.com/v1beta/projects/<GOOGLE_APP_ID>:exchangeDebugToken 
 - HTTP status code: 403 
 - Response body: {
  "error": {
    "code": 403,
    "message": "Requests from this iOS client application \u003cempty\u003e are blocked.",
    "status": "PERMISSION_DENIED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "API_KEY_IOS_APP_BLOCKED",
        "domain": "googleapis.com",
        "metadata": {
          "consumer": "projects/<my project #",
          "service": "firebaseappcheck.googleapis.com"
        }
      }
    ]
  }
}
}

requestAppAttestToken() 返回错误:

App Attest error: Error Domain=com.firebase.appCheck Code=0 "(null)"

GCP Console 确实显示了对以下有 100% 错误的所有调用:

google.firebase.appcheck.v1beta.TokenExchangeService.ExchangeDebugToken 
    google.firebase.appcheck.v1beta.TokenExchangeService.ExchangeDeviceCheckToken   
    google.firebase.appcheck.v1beta.TokenExchangeService.GenerateAppAttestChallenge 

所有这些似乎都指向权限错误?具体来说,GOOGLE_APP_ID 位于请求 URL 中,但 App Check 是通过控制台在 Firebase 中配置的...

我没有在文档中看到任何内容,也没有在 IAM 中看到任何我错过的明显内容? :(

提前寻求帮助!

更新 经过与 Postman 的进一步测试后:

问题似乎是 SDK 在调用 AppCheck API 时未正确传递

X-Ios-Bundle-Identifier

得出此结论的步骤:

  • 来自 POSTMAN:使用原始 API_KEY 的 API 调用 -> 产生初始(上面)错误响应/403
  • 来自 POSTMAN:如上所述的 API 调用,+ X-Ios-Bundle-Identifier + 有效的 debug_token -> 产生成功的有效负载。

所以:

  • 有什么想法可以帮助识别为什么 SDK 没有传递
    X-Ios-Bundle-Identifier
    吗? 该应用程序正在使用其他 Firebase API,没有问题,因此似乎仅限于 AppCheck SDK...
  • 和/或 - 能否以编程方式将
    X-Ios-Bundle-Identifier
    添加(在 Swift 中)到 AppCheck 调用中(在 .plist 中正确注释)

已解决!

App Check SDK 目前不支持 API 密钥的 Android / iOS 应用程序限制。因此,您必须删除 API 密钥的应用程序限制才能解决此问题。

希望应用程序限制能够在某个时候得到支持......

更新!

v8.8.0-beta 现在支持捆绑 ID! :)

ios firebase firebase-app-check
4个回答
6
投票

1。配置DeviceCheck的私钥

  • 确保您已为 DeviceCheck 创建私钥 enter image description here

  • 并将其安装在 AppCheck 选项卡下的 Firebase 项目设置中 enter image description here

https://firebase.google.com/docs/app-check/ios/devicecheck-provider

2。将调试令牌添加到 firebase。

如果您使用AppCheckDebugProvider(主要用于模拟器),运行项目后您将在控制台中看到一个调试令牌,您需要将其复制并添加到项目设置的AppCheck中。 AppCheck 会批准它。另外,不要忘记为

-FIRDebugEnabled
添加
Arguments Passed on Launch

https://firebase.google.com/docs/app-check/ios/debug-provider

3.添加 AppAttest 环境的生产权限。

AppCheck Beta 版不适用于 AppAttest 开发环境,因此您需要在您的权利中设置

production
环境。默认情况下,AppAttest 在开发环境中运行,无论您在市场上的选择如何,它都可以在生产环境中运行。

https://firebase.google.com/docs/app-check/ios/app-attest-provider

https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_devicecheck_appattest-environment

enter image description here

4。可选:

可以简化代码

#if targetEnvironment (simulator)
    let providerFactory = AppCheckDebugProviderFactory ()
#else
    let providerFactory = CustomAppCheckProviderFactory ()
#endif

AppCheck.setAppCheckProviderFactory (providerFactory)

并获得代币

if let fbApp = FirebaseApp.app () {
    providerFactory.createProvider(with: fbApp)?.getToken { token, error in
        if let token = token {
            print ("AppCheck token: \ (token.token), expiration date: \ (token.expirationDate)")
        } else if let error = error {
            print ("AppCheck error: \ (error as NSError).userInfo)")
        }
    }
}

或者如果你想保护非 Firebase 资源,你可以获得这样的令牌:

AppCheck.appCheck().token (forcingRefresh: false) { token, error in
    if let token = token {
        print ("AppCheck token: \ (token.token), expiration date: \ (token.expirationDate)")
    } else if let error = error {
        print ("AppCheck error: \ (error as NSError).userInfo)")
    }
}

https://firebase.google.com/docs/app-check/ios/custom-resource


4
投票

App Check SDK 目前不支持 API 密钥的 Android / iOS 应用程序限制。因此,您必须删除 API 密钥的应用程序限制才能解决此问题。

希望应用程序限制能够在某个时候得到支持......


1
投票

出现此错误 - 这对我有用:

  • 在真实的 Android 设备上运行应用程序
  • 打开Android Studio→Logcat→搜索“DebugAppCheckProvider”→复制调试密钥
  • 在 Firebase 中,转到“应用程序检查”→ 应用程序→ 3 点菜单→ 管理调试令牌→ 添加令牌→ 为其命名→ 粘贴调试密钥
  • 添加应用程序激活检查后令牌的控制台日志。
  try {
      await firebase.appCheck().activate("ignored", true);
      const token = await getAppCheckToken();
      console.log({ token });
   } catch (err) {      
      console.error(err);
   }
};

0
投票

可能是您没有在您的功能中启用App Attest:

enter image description here

标识符

不要忘记在 Xcode 中添加相同的功能:

enter image description here

转到“目标”-> 您的目标-> 签名和功能-> 按“添加功能”并选择“应用程序证明”。

© www.soinside.com 2019 - 2024. All rights reserved.