Android 获取谷歌一次性授权码

Android 获取谷歌一次性授权码,android,ruby-on-rails,google-authentication,google-cloud-platform,Android,Ruby On Rails,Google Authentication,Google Cloud Platform,我无法从谷歌获得一次性授权码。我正在尝试从Android客户端获取授权代码,以便将其发送到Rails后端(web客户端) 在我的Google Cloud Developer控制台中,我有一个具有两个客户端ID的应用程序: web应用程序的客户端ID(用于my rails后端) Android应用程序的客户端ID(适用于我的Android客户端)。使用的SHA1来自~/.android/debug.keystore 假设Web应用程序客户端ID为12345.apps.googleuserconte

我无法从谷歌获得一次性授权码。我正在尝试从Android客户端获取授权代码,以便将其发送到Rails后端(web客户端)

在我的Google Cloud Developer控制台中,我有一个具有两个客户端ID的应用程序:

  • web应用程序的客户端ID(用于my rails后端)

  • 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);
        }
    
    这篇文章和几篇SO帖子建议我需要设置
    access\u 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";
    
    这很有帮助。此外,是否说明:

    [注意:此策略正在逐步推出。目前,当涉及访问令牌时,仅当请求的范围包括

    我将在回答中总结一下令牌交换是否在Rails后端工作。

    以下是我所做的:

    final String authToken = GoogleAuthUtil.getTokenWithNotification (this.context, account.name, "oauth2:" + AuthUtils.profileScope, new Bundle (),
                    Contract.authority, new Bundle ());
    
    但是,对于前台活动,getToken也应该起同样的作用

    使用此令牌,将其发送到服务器,发送方式可以像HTTP头(通过HTTPS)一样使用。只要服务器作用域是用于获取令牌的作用域的子集,就不会有问题。服务器使用服务器id,android客户端使用安卓客户端id

    您应该将范围设置为:

    oauth2:https://www.googleapis.com/auth/calendar
    

    编辑:好的,我知道你想做什么了。范围值是一个空格分隔的列表,因此你可能需要将访问群体:服务器:客户端\u id:附加到你的范围中,如:

    "oauth2:https://www.googleapis.com/auth/calendar audience:server:client_id:12345-your-web-component-client-id"
    

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

  • 确保在同一个谷歌云控制台项目中正确设置了Android和Web客户端ID

  • 使用正确的作用域。即使您仅访问日历api,也需要登录:

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

    私有最终静态字符串WEB_CLIENT_ID=“12345.apps.googleusercontent.com”; 私有最终静态字符串GOOGLE_CALENDAR_API_SCOPE=“oauth2:服务器:客户端id:”+WEB_客户端id+”:API_SCOPE:”


  • 感谢您的回复。上面的作用域返回一个GoogleAuthException——“无效的作用域”。我想这是因为Google只需要同一项目中的客户端授权一次。我想这就是他们所说的,如何使用GoogleAuthUtil.getToken()获得脱机授权代码(access_type=offline)?你成功做到了吗?@grebulon是的,我通过GoogleAuthUtil.getToken()获得了一次性授权代码在完成接受答案中的内容后。我将一次性授权代码发送到我们的后端服务器,该服务器使用该代码获取google api令牌。我几乎可以让它工作了……在我的流程中,我不断获取UserRecoverableAuthException(NeedPermission)对于脱机权限。启动接收到的intent并调用getToken,在无限循环中再次启动脱机权限的添加权限对话框,依此类推。您应该开始一个新问题并发布一些代码
    oauth2:https://www.googleapis.com/auth/calendar.readonly
    
    "oauth2:https://www.googleapis.com/auth/calendar audience:server:client_id:12345-your-web-component-client-id"