android 播放完整性API调用:如何处理GoogleServer不可用错误

enyaitl3  于 2023-01-19  发布在  Android
关注(0)|答案(1)|浏览(208)

我正在开发一个Android安全应用程序,并决定实现PlayIntegrity API作为SafetyNet API的替代方案。我已经完成了启用Play和Cloud控制台等必要的设置步骤,然而,我遇到了一个问题,我得到一个错误'谷歌服务器不可用'当试图获得令牌。任何人都可以提供任何见解,为什么会发生这种情况和可能的解决方案?任何帮助都将不胜感激。

Please see below code: 

        @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // playIntegritySetup.lol();
        getToken();
    }

    private void getToken() {
        String nonce = Base64.encodeToString(generateNonce(50).getBytes(),   Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);

        // Create an instance of a manager.
        IntegrityManager integrityManager = IntegrityManagerFactory.create(getApplicationContext());

        // Request the integrity token by providing a nonce.
        Task<IntegrityTokenResponse> integrityTokenResponse = integrityManager.requestIntegrityToken(
                IntegrityTokenRequest.builder()
                        .setNonce(nonce)
                        .build());

        integrityTokenResponse.addOnSuccessListener(new OnSuccessListener<IntegrityTokenResponse>() {
            @Override
            public void onSuccess(IntegrityTokenResponse integrityTokenResponse) {
                String integrityToken = integrityTokenResponse.token();
                SplashActivity.this.doIntegrityCheck(integrityToken);
                Log.e("Integrity Token", "integrity token from the app" + integrityToken);

            }
        });

        integrityTokenResponse.addOnFailureListener(e -> showErrorDialog("Error getting token from Google. Google said: " + getErrorText(e)));
    }

    private void doIntegrityCheck(String token) {
        AtomicBoolean hasError = new AtomicBoolean(false);

        Observable.fromCallable(() -> {

                    OkHttpClient okHttpClient = new OkHttpClient();
                    Response response = okHttpClient.newCall(new Request.Builder().url("money control url" + "token from backend server" + token).build()).execute();
                    Log.e("Token", "token from the app" + token);

                    if (!response.isSuccessful()) {
                        hasError.set(true);
                        return "Api request error. Code: " + response.code();

                    }
                    ResponseBody responseBody = response.body();
                    if (responseBody == null) {
                        hasError.set(true);

                        return "Api request error. Empty response";

                    }
                    JSONObject responseJson = new JSONObject(responseBody.string());
                    if (responseJson.has("error")) {
                        hasError.set(true);

                        return "Api request error: " + responseJson.getString("error");

                    }
                    if (!responseJson.has("deviceIntegrity")) {
                        hasError.set(true);

                    }

                    return responseJson.getJSONObject("deviceIntegrity").toString();
                }) // Execute in IO thread, i.e. background thread.
                .subscribeOn(Schedulers.io())
                // report or post the result to main thread.
                .observeOn(AndroidSchedulers.mainThread())
                // execute this RxJava
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(String result) {
                        if (hasError.get()) {
                            if (result.contains("MEETS_DEVICE_INTEGRITY") && result.contains("MEETS_BASIC_INTEGRITY")) {
                               //Here goes my other code

                            }
                        }
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }



  private String getErrorText(Exception e) {
        String msg = e.getMessage();
        if (msg == null) {
            return "Unknown Error";
        }

        //the error code
        int errorCode = Integer.parseInt(msg.replaceAll("\n", "").replaceAll(":(.*)", ""));
        switch (errorCode) {
            case IntegrityErrorCode.API_NOT_AVAILABLE:
                return "API_NOT_AVAILABLE";
            case IntegrityErrorCode.NO_ERROR:
                return "NO_ERROR";
            case IntegrityErrorCode.INTERNAL_ERROR:
                return "INTERNAL_ERROR";
            case IntegrityErrorCode.NETWORK_ERROR:
                return "NETWORK_ERROR";
            case IntegrityErrorCode.PLAY_STORE_NOT_FOUND:
                return "PLAY_STORE_NOT_FOUND";
            case IntegrityErrorCode.PLAY_STORE_ACCOUNT_NOT_FOUND:
                return "PLAY_STORE_ACCOUNT_NOT_FOUND";
            case IntegrityErrorCode.APP_NOT_INSTALLED:
                return "APP_NOT_INSTALLED";
            case IntegrityErrorCode.PLAY_SERVICES_NOT_FOUND:
                return "PLAY_SERVICES_NOT_FOUND";
            case IntegrityErrorCode.APP_UID_MISMATCH:
                return "APP_UID_MISMATCH";
            case IntegrityErrorCode.TOO_MANY_REQUESTS:
                return "TOO_MANY_REQUESTS";
            case IntegrityErrorCode.CANNOT_BIND_TO_SERVICE:
                return "CANNOT_BIND_TO_SERVICE";
            case IntegrityErrorCode.NONCE_TOO_SHORT:
                return "NONCE_TOO_SHORT";
            case IntegrityErrorCode.NONCE_TOO_LONG:
                return "NONCE_TOO_LONG";
            case IntegrityErrorCode.GOOGLE_SERVER_UNAVAILABLE:
                return "GOOGLE_SERVER_UNAVAILABLE";
            case IntegrityErrorCode.NONCE_IS_NOT_BASE64:
                return "NONCE_IS_NOT_BASE64";
            default:
                return "Unknown Error";
        }
    }

    private String generateNonce(int length) {
        String nonce = "";
        String allowed = getNonce();
        for (int i = 0; i < length; i++) {
            nonce = nonce.concat(String.valueOf(allowed.charAt((int) Math.floor(Math.random() * allowed.length()))));
        }
        return nonce;
    }

    public native String getNonce();

    static {
        System.loadLibrary("all-keys");
    }
zzzyeukh

zzzyeukh1#

我遇到了同样的问题,我找到了解决办法。
当您在Google Play之外工作时,您需要指定cloudProjectNumber(),这可以在Google云控制台中找到。
引用自the doc
重要提示:为了接收和解密Integrity API响应,Google Play上不可用的应用需要在其请求中包含其Cloud项目编号。您可以在Google Cloud Console的项目信息中找到此编号。
所以代码应该是这样的:

IntegrityTokenRequest.builder()
                        .setNonce(nonce)
                        .cloudProjectNumber(100004676) // your cloud project number here for dev build
                        .build());

相关问题