保护 Firebase ML Android 应用的 Cloud 凭据

如果您的 Android 应用使用了 Firebase ML 的某个云端 API,那么在生产环境中发布该应用之前,应该采取一些额外的措施来防止未经授权的 API 访问。

对于您的正式版应用,您应确保只有经过身份验证的客户端才能访问云端服务。(请注意,只有未启用 root 权限的设备才能使用所述方法进行身份验证。)

另外,您要创建一个仅用于调试的 API 密钥,以便在测试和开发期间使用。

1. 在 Firebase 中注册正式版应用

首先,在 Firebase 中注册您的正式版应用。

  1. 确保您拥有应用的 SHA-1 签名。请参阅对客户端进行身份验证,了解具体操作方法。

  2. 在 Firebase 控制台中,依次点击 和“项目设置”,然后选择“设置”标签页。

  3. 向下滚动到“您的应用”卡片,然后选择您的 Android 应用。

  4. 将应用的 SHA-1 签名添加到应用的信息中。

2. 限制 API 密钥的范围

接下来,配置现有的 API 密钥以禁止访问 Cloud Vision API:

  1. 打开 Google Cloud 控制台中的凭据页面。收到提示时,选择您的项目。

  2. 针对列表中的每个现有 API 密钥,打开修改视图。

  3. 在“API 限制”部分中,选择限制密钥,然后向列表中添加您希望此 API 密钥有权访问的所有 API。切勿包含 Cloud Vision API。

    在配置 API 密钥的 API 限制时,您应明确声明该密钥有权访问的 API。默认情况下,如果在“API 限制”部分中选择“不限制密钥”,即表示一个 API 密钥可用于访问已为项目启用的所有 API。

现在,您现有的 API 密钥不会授予对云端机器学习服务的访问权限,但对于您添加到每个密钥的“API 限制”列表中的任何 API,仍可继续使用该密钥进行访问。

请注意,如果您日后启用任何其他 API,必须将其添加到相应 API 密钥的“API 限制”列表中。

3. 创建并使用仅用于调试的 API 密钥

最后,创建一个仅用于开发的新 API 密钥。Firebase ML 可以使用此 API 密钥在无法进行应用身份验证的环境中访问 Google Cloud 服务,例如在模拟器上运行时。

  1. 创建一个用于开发的新 API 密钥:

    1. 打开 Google Cloud 控制台中的凭据页面。收到提示时,选择您的项目。

    2. 依次点击创建凭据 > API 密钥,并记下新的 API 密钥。此密钥允许从未经身份验证的应用访问 API,因此请勿泄露此密钥

  2. 为确保新的调试 API 密钥不会在发布的应用中泄露,请在仅用于调试 build 的 Android 清单文件中指定调试 API 密钥:

    1. 如果您还没有调试清单,请创建一个,只需依次点击文件 > 新建 > 其他 > Android 清单文件,并从目标源代码集中选择 debug 即可。

    2. 在调试清单中,添加以下声明:

      <application>
      <meta-data
          android:name="com.firebase.ml.cloud.ApiKeyForDebug"
          android:value="your-debug-api-key" />
      </application>
      
  3. 在您的应用中,配置 Firebase ML 以使用证书指纹匹配来对生产环境中的客户端进行身份验证,并确保只在调试 build 中使用调试 API 密钥:

    Kotlin+KTX

    val optionsBuilder = FirebaseVisionCloudImageLabelerOptions.Builder()
    if (!BuildConfig.DEBUG) {
        // Requires physical, non-rooted device:
        optionsBuilder.enforceCertFingerprintMatch()
    }
    
    // Set other options. For example:
    optionsBuilder.setConfidenceThreshold(0.8f)
    // ...
    
    // And lastly:
    val options = optionsBuilder.build()
    FirebaseVision.getInstance().getCloudImageLabeler(options).processImage(myImage)

    Java

    FirebaseVisionCloudImageLabelerOptions.Builder optionsBuilder =
            new FirebaseVisionCloudImageLabelerOptions.Builder();
    if (!BuildConfig.DEBUG) {
        // Requires physical, non-rooted device:
        optionsBuilder.enforceCertFingerprintMatch();
    }
    
    // Set other options. For example:
    optionsBuilder.setConfidenceThreshold(0.8f);
    // ...
    
    // And lastly:
    FirebaseVisionCloudImageLabelerOptions options = optionsBuilder.build();
    FirebaseVision.getInstance().getCloudImageLabeler(options).processImage(myImage);

后续步骤

如需了解在使用其他 Firebase 功能时的应用发布准备工作,请参阅发布核对清单