【问题标题】:Failed to restrict API key with Google Cloud Translation API无法使用 Google Cloud Translation API 限制 API 密钥
【发布时间】:2017-12-24 13:04:23
【问题描述】:

要使用谷歌翻译 api,我已经创建了 API 密钥,当我使用下面的代码时,我没有问题:

private String translateText(String toTrasnlate){
TranslateOptions options = TranslateOptions.newBuilder()
        .setApiKey("XXXXXXXXXXXXXXXXXXXXX_XXXXXXXX")
        .build();
Translate translate = options.getService();
Translation translation = translate.translate(toTrasnlate, Translate.TranslateOption.targetLanguage("en"));
return translation.getTranslatedText();
}

但是当我在谷歌开发者控制台中使用 SHA1 密钥和包添加限制时,我跳过了以下错误,你知道为什么会这样,我可以在哪里继续? 问候和感谢。

07-12 14:23:39.491 805-805/com.example.translator E/AndroidRuntime: FATAL EXCEPTION: main

Process: com.example.translator, PID: 805
com.google.cloud.translate.TranslateException: Requests from this Android client application <empty> are blocked.
at com.google.cloud.translate.spi.v2.HttpTranslateRpc.translate(HttpTranslateRpc.java:61)
at com.google.cloud.translate.spi.v2.HttpTranslateRpc.translate(HttpTranslateRpc.java:143)
at com.google.cloud.translate.TranslateImpl$4.call(TranslateImpl.java:113)
at com.google.cloud.translate.TranslateImpl$4.call(TranslateImpl.java:110)
at com.google.api.gax.retrying.DirectRetryingExecutor.submit(DirectRetryingExecutor.java:94)
at com.google.cloud.RetryHelper.runWithRetries(RetryHelper.java:54)
at com.google.cloud.translate.TranslateImpl.translate(TranslateImpl.java:110)
at com.google.cloud.translate.TranslateImpl.translate(TranslateImpl.java:124)
at com.example.translator.MainActivity.translateText(MainActivity.java:347)
at com.example.translator.MainActivity.access$500(MainActivity.java:46)
at com.example.translator.MainActivity$5.onClick(MainActivity.java:121)
at android.view.View.performClick(View.java)
at android.view.View$PerformClick.run(View.java)
at android.os.Handler.handleCallback(Handler.java)
at android.os.Handler.dispatchMessage(Handler.java)
at android.os.Looper.loop(Looper.java)
at android.app.ActivityThread.main(ActivityThread.java)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
Caused by: com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden

{                                                                                  
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Requests from this Android client application <empty> are blocked.",
"reason" : "forbidden"
} ],
"message" : "Requests from this Android client application <empty> are blocked.",
"status" : "PERMISSION_DENIED"
}

at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:321)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1056)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at com.google.cloud.translate.spi.v2.HttpTranslateRpc.translate(HttpTranslateRpc.java:129)
... 19 more

【问题讨论】:

  • 兄弟你找到解决办法了吗?

标签: android google-translate


【解决方案1】:

现在可能为时已晚,但这就是它的完成方式:

val headers: Map<String, String> = ImmutableMap.of(
            "X-Android-Package", context.packageName,
            "X-Android-Cert", (getApplicationSignature(context)[0])
    )

val options = TranslateOptions.newBuilder()
            .setApiKey(apiKey)
            .setHeaderProvider { headers }
            .build()

并获得 SHA1:

fun getApplicationSignature(context: Context, packageName: String = context.packageName): List<String> {
val signatureList: List<String>
try {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        // New signature
        val sig = context.packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNING_CERTIFICATES).signingInfo
        signatureList = if (sig.hasMultipleSigners()) {
            // Send all with apkContentsSigners
            sig.apkContentsSigners.map {
                val digest = MessageDigest.getInstance("SHA1")
                digest.update(it.toByteArray())
                bytesToHex(digest.digest())
            }
        } else {
            // Send one with signingCertificateHistory
            sig.signingCertificateHistory.map {
                val digest = MessageDigest.getInstance("SHA1")
                digest.update(it.toByteArray())
                bytesToHex(digest.digest())
            }
        }
    } else {
        val sig = context.packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES).signatures
        signatureList = sig.map {
            val digest = MessageDigest.getInstance("SHA1")
            digest.update(it.toByteArray())
            bytesToHex(digest.digest())
        }
    }

    return signatureList
} catch (e: Exception) {
    // Handle error
}
return emptyList()
}



fun bytesToHex(bytes: ByteArray): String {
    val hexArray = charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F')
    val hexChars = CharArray(bytes.size * 2)
    var v: Int
    for (j in bytes.indices) {
        v = bytes[j].toInt() and 0xFF
        hexChars[j * 2] = hexArray[v.ushr(4)]
        hexChars[j * 2 + 1] = hexArray[v and 0x0F]
    }
    return String(hexChars)
}

【讨论】: