获取Google一次性授权码

mik*_*r85 9 android ruby-on-rails google-authentication google-cloud-platform

我无法从Google获取一次性授权码.我试图从Android客户端获取授权代码,以便我可以将其发送到我的Rails后端(Web客户端).

在我的Google Cloud Developer Console中,我有一个带有两个客户端ID的应用程序:

  1. Web应用程序的客户端ID(用于我的rails后端)

  2. Android应用程序的客户端ID(对于我的Android客户端).使用的SHA1来自〜/ .android/debug.keystore

假设Web应用程序客户端ID是 12345.apps.googleusercontent.com

假设Android客户端ID是 67890.apps.googleusercontent.com

这是我的一些代码:

private final static String WEB_CLIENT_ID = "12345.apps.googleusercontent.com";
private final static String GOOGLE_CALENDAR_API_SCOPE = "audience:server:client_id:" + WEB_CLIENT_ID;

private void getAndUseAuthToken(final String email) {
        AsyncTask task = new AsyncTask<String, Void, String>() {
            @Override
            protected String doInBackground(String... emails) {
                try {
                    return GoogleAuthUtil.getToken(AddExternalCalendarsActivity.this, emails[0], GOOGLE_CALENDAR_API_SCOPE);
                } catch (UserRecoverableAuthException e) {
                    startActivityForResult(e.getIntent(), IntentConstants.REQUEST_GOOGLE_AUTHORIZATION);
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (GoogleAuthException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                return null;
            }

            @Override
            protected void onPostExecute(String authToken) {
                if (authToken != null) {
                    saveTokenAndGetCalendars(email, authToken);
                }
            }
        };

        String[] emails = new String[1];
        emails[0] = email;
        task.execute(emails);
    }
Run Code Online (Sandbox Code Playgroud)

一些额外的说明

  • 我正在点击GoogleAuthException并收到"Unknown"作为消息详细信息

  • 我无法在此项目的Google云端控制台权限中添加其他成员 - 添加新成员时,弹出窗口显示"服务器错误.哎呀!我们不好.".我已经两次向Google发送反馈.

  • 我指的是这个文档.请注意下面的引用.通过"修复",他们是否说我不需要在GOOGLE_CALENDAR_API_SCOPE变量中添加受众:server:client_id?我已经尝试过和不使用,但仍然得到相同的GoogleAuthException.

在这种情况下,Android应用可以代表设备上的任何Google帐户调用GoogleAuthUtil.getToken()方法,并且范围参数值为audience:server:client_id:9414861317621.apps.googleusercontent.com.前缀audience:server:client_id:是固定的,作用域字符串的其余部分是Web组件的客户端ID.

  • 如果我使用此范围,我可以使用谷歌设备进行身份验证.但是,我读过的文档表明,我需要在范围内使用服务器Web客户端ID(与Android客户端ID在同一个google控制台项目中),以便服务器代表google api在Android客户端上授权它的用户:

    private final static String GOOGLE_CALENDAR_API_SCOPE = "oauth2:https://www.googleapis.com/auth/calendar";

更新1

我最初在回答中添加: 我的第一个问题的原因 - 我正在点击GoogleAuthException并接收"Unknown"作为消息详细信息 - 这是我在云控制台中添加android客户端ID时犯的错误.SHA1是正确的但我没有正确输入包名称.当我的android包实际上是com.company.android.app时,我使用了com.company.app.原始问题中的代码运行正常.只需确保您的Google Cloud Console项目中包含所有必需的客户.

但另一个问题仍然存在.当我将从GoogleAuthUtil.getToken()返回的一次性授权令牌发送到Rails后端,然后尝试将其交换为access_token和refresh_token时,我得到以下内容:

Signet::AuthorizationError:
  Authorization failed.  Server message:
  {
      "error" : "invalid_grant"
  }
Run Code Online (Sandbox Code Playgroud)

这个谷歌文档和几个SO帖子表明我需要设置access_type=offline.但我认为,当您从Web服务器请求一次性授权代码和脱机访问时.我正在尝试从Android客户端请求一次性授权代码并将其发送到Web服务器.

这可能与GoogleAuthUtil.getToken()有关吗?

更新2

即使您只是尝试访问日历,Google Plus登录也必须在范围内:

private final static String GOOGLE_CALENDAR_API_SCOPE = "oauth2:server:client_id:" + WEB_CLIENT_ID + ":api_scope:https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/calendar";
Run Code Online (Sandbox Code Playgroud)

这篇SO帖子很有帮助.此外,Google的Cross Client身份文档确实说明:

[注:此政策正在逐步推出.目前,当涉及访问令牌时,它仅适用于请求的范围包括https://www.googleapis.com/auth/plus.login.

如果令牌交换在Rails后端工作,我会在答案中总结.

mik*_*r85 3

有两件事为我解决了这个问题:

  1. 确保在同一 Google Cloud Console 项目中正确设置 Android 和 Web 客户端 ID。

  2. 使用正确的范围。即使您只访问日历 api,也需要登录:

    // 正在交换访问令牌和刷新令牌的身份验证代码的 Web 服务器的 ID

    私有最终静态字符串 WEB_CLIENT_ID = "12345.apps.googleusercontent.com"; 私人最终静态字符串GOOGLE_CALENDAR_API_SCOPE =“oauth2:服务器:client_id:”+ WEB_CLIENT_ID +“:api_scope:https: //www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/calendar ” ;