请求缺少必需的身份验证凭据。预期的OAuth 2访问令牌

时间:2020-05-29 17:07:04

标签: android google-signin

我们正在尝试将Google Sign选项添加到我们的项目中。我们已成功将此选项添加到站点和ios应用程序中。但是在添加到android应用程序时遇到了困难。使用此页面https://developers.google.com/identity/sign-in/android/start-integrating中的“配置项目”选项,我指定Andrid调试键(Gradle-> android-> signingReport)的SHA1和程序包名称(com.my.app)。该表格为我们提供了WEB类型的客户端ID。我下载了certificate.json并将其放在项目的app文件夹中。我还在Google API控制台中找到了具有指定SHA1哈希值的android类型客户端ID,但我不知道在哪里使用它(如果我们使用android类型oauth客户端,则会收到错误消息“ signInResult:failed code = 10”,因此我们应该使用网络类型客户端,并且在API控制台中没有此类android客户端,我们会收到12500错误且没有令牌。

接下来,我们根据此文档https://developers.google.com/identity/sign-in/android/backend-auth添加了示例代码来获取令牌并将其传递到后端服务器。

private void enterGoogle() {
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestEmail()
                .requestIdToken("12345-OurWebTypeClient.apps.googleusercontent.com").build();
        mGoogleSignInClient = GoogleSignIn.getClient(this, gso);

        Intent signInIntent = mGoogleSignInClient.getSignInIntent();
        startActivityForResult(signInIntent, RC_SIGN_IN);
    }

    private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
        try {
            GoogleSignInAccount account = completedTask.getResult(ApiException.class);

            String accessToken = account.getIdToken();
            authWithGoogleToken(accessToken);

        } catch (ApiException e) {
            // The ApiException status code indicates the detailed failure reason.
            // Please refer to the GoogleSignInStatusCodes class reference for more information.
            Log.w(TAG, "signInResult:failed code=" + e.getStatusCode());

        }
    }

    private void authWithGoogleToken(String accessToken) {
        if (accessToken == null)
            Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show();
        else
            RetrofitFactory.getInstance().authGoogle(accessToken)
                .enqueue(new retrofit2.Callback<JsonObject>() {
                    @Override
                    public void onResponse(retrofit2.Call<JsonObject> call, retrofit2.Response<JsonObject> response) {
                        try {
                            if (response.isSuccessful() && response.body() != null) {
                                if (!response.body().has("error")) {

                                    Toast.makeText(MainActivity.this, "Success!", Toast.LENGTH_SHORT).show();
                                } else {
                                    Toast.makeText(MainActivity.this, response.body().get("error").getAsString(), Toast.LENGTH_SHORT).show();
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show();
                        }
                    }

                    @Override
                    public void onFailure(retrofit2.Call<JsonObject> call, Throwable t) {
                        Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show();
                    }
                });
    }

使用此代码,我们获得了从“ eyJ”开始的长令牌。如果我们稍微更改代码以使用替代方法:

.requestServerAuthCode("12345-OurWebTypeClient.apps.googleusercontent.com").build();

String accessToken = completedTask.getResult().getServerAuthCode();

我们获得了以“ 4/0”开头的简短令牌。我们不知道这两种类型的令牌与两种获取令牌的方法之间有什么区别,但是在后端服务器上,两种类型的令牌都出现一个错误:

{
  "error": {
    "code": 401,
    "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
    "status": "UNAUTHENTICATED"
  }
}

例如,对于iOS SDK中的令牌,我们没有此类错误。请帮助找出在Android应用程序中实施Google登录存在什么问题?

1 个答案:

答案 0 :(得分:0)

我们使用此变通办法解决了该问题

GoogleSignInAccount account = completedTask.getResult(ApiException.class);
            AsyncTask.execute(() -> {
                try {
                    String accessToken = GoogleAuthUtil.getToken(context, account.getAccount(), "oauth2:" + Scopes.PLUS_LOGIN);
                    runOnUiThread(() -> {
                        authWithGoogleToken(accessToken);
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });

            String accessToken = account.getIdToken();
            authWithGoogleToken(accessToken);