You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS端Firebase App Check 403 PERMISSION_DENIED权限错误如何解决

iOS端Firebase App Check出现403 PERMISSION_DENIED权限错误解决方案

问题背景

已按官方文档完成App Check启用配置,项目引入对应SDK,AppDelegate的Token配置代码如下:

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)")
    }
  }
}

报错信息

三个Token请求均返回异常:

  • requestDeviceCheckToken()返回403权限错误:
DeviceCheck error: ["NSLocalizedFailureReason": 服务器返回错误:
 - URL: https://firebaseappcheck.googleapis.com/v1beta/projects/<GOOGLE_APP_ID>:exchangeDeviceCheckToken
 - HTTP状态码: 403
 - 响应体: {
  "error": {
    "code": 403,
    "message": "来自该iOS客户端应用<empty>的请求被拦截",
    "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()返回403权限错误:
Debug error: Error Domain=com.firebase.appCheck Code=0 "服务器返回错误:
 - URL: https://firebaseappcheck.googleapis.com/v1beta/projects/<GOOGLE_APP_ID>:exchangeDebugToken
 - HTTP状态码: 403
 - 响应体: {
  "error": {
    "code": 403,
    "message": "来自该iOS客户端应用<empty>的请求被拦截",
    "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=服务器返回错误:
 - URL: https://firebaseappcheck.googleapis.com/v1beta/projects/<GOOGLE_APP_ID>:exchangeDebugToken
 - HTTP状态码: 403
 - 响应体: {
  "error": {
    "code": 403,
    "message": "来自该iOS客户端应用<empty>的请求被拦截",
    "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控制台显示以下接口调用错误率为100%:

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

问题排查

经过测试确认,问题根源为SDK调用AppCheck接口时未正确传递X-Ios-Bundle-Identifier头:

  • 仅用原始API_KEY调用接口,返回上述403错误
  • 同请求补充X-Ios-Bundle-Identifier和有效debug_token后,调用成功返回正常结果

解决方案

  • v8.8.0-beta以下旧版SDK:旧版App Check SDK不支持API密钥的Android/iOS应用限制规则,暂时移除API密钥的应用限制即可解决问题。
  • v8.8.0-beta及以上新版SDK:该版本及更高版本的SDK已原生支持bundle ID校验能力,无需额外配置即可正常适配API密钥的应用限制规则。

内容的提问来源于stack exchange,提问作者jminutaglio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 06:09:03