【问题标题】:gapi grantOfflineAccess access_code to refresh_tokengapi grantOfflineAccess access_code to refresh_token
【发布时间】:2017-09-05 14:35:56
【问题描述】:

至少到今年 6 月底(2017 年)为止(我的用户是老师的,所以在夏天不要经常访问我们的应用程序......)我有以下工作流程。

用户可以使用 gapi 库通过网络登录。对于新用户,成功登录会调用

gapi.auth2.getAuthInstance().currentUser.get().grantOfflineAccess()

获取一个代码,然后将其发送到我们的 Java 后端以将代码交换为 refresh_token。我们使用 google-api-client 库 (v 1.22.0) 来验证用户在初始登录时返回的 id_token,然后通过 REST 调用来获取返回的 refresh_token。

HttpClient client   = new DefaultHttpClient();
HttpPost post       = new HttpPost("https://www.googleapis.com/oauth2/v4/token");
List<NameValuePair> pairs = new ArrayList<NameValuePair>();
pairs.add(new BasicNameValuePair("code", r.getRefreshCode()));
pairs.add(new BasicNameValuePair("redirect_uri", "postmessage"));
pairs.add(new BasicNameValuePair("client_id", clientInfo.getClientId()));
pairs.add(new BasicNameValuePair("client_secret", clientInfo.getClientSecret()));
pairs.add(new BasicNameValuePair("grant_type", "authorization_code"));
post.setEntity(new UrlEncodedFormEntity(pairs));
org.apache.http.HttpResponse response = client.execute(post);
String responseBody = EntityUtils.toString(response.getEntity());

至少在 6 月之前,REST 调用返回以下格式的 JSON 对象

{
  access_token: '',
  token_type: '',
  expires_in: 3600,
  id_token: '',
  refresh_token: ''
}

...但是现在(无论如何在过去几周内),刷新令牌不包含在 REST 调用的响应中。

发生了什么变化,或者我需要做些什么不同的事情来获取我们的服务器使用的 refresh_token?

在 Google 提供的 OAuth 2.0 Playground 中,当我使用与我的应用程序相同的范围并将“代码”交换为刷新令牌时,我会通过

返回一个对象
{
  "access_token": "", 
  "token_type": "", 
  "expires_in": 3600, 
  "refresh_token": ""
}

所以,显然 Playground 所做的事情与我不同。我查看了 Chrome 调试器中发送的请求,它看起来与我正在执行的操作相似。

【问题讨论】:

    标签: google-api google-oauth google-api-java-client google-api-js-client


    【解决方案1】:

    我通过修改 grantOfflineAccess 调用以包含以下内容解决了这个问题...

    gapi.auth2.getAuthInstance().currentUser.get().grantOfflineAccess({
      access_type: 'offline',
      prompt:      'consent',
      scope:       SCOPES.join(' ')
    })
    

    ...重要的补充是提示。据我所知,提供离线访问许可的窗口已自动关闭,因此返回的代码无法在 Java 端生成刷新令牌。

    另外,我更新了 Java 代码以使用 Google 客户端库而不是直接调用 REST(尽管 JS 更改仍然导致使用 REST 调用检索刷新令牌,所以这只是为了保持一致性)。

    GoogleAuthorizationCodeTokenRequest request = 
      new GoogleAuthorizationCodeTokenRequest(new NetHttpTransport(), new JacksonFactory(),
                                      clientInfo.getClientId(), clientInfo.getClientSecret(),
                                      r.getRefreshCode(), "postmessage");
    request.setGrantType("authorization_code");
    GoogleTokenResponse response = request.execute();
    

    【讨论】:

    • 您发布的以下代码是基于java 的解决方案,操作员的问题是关于基于c# 的代码。
    • 不。我的问题是 JavaScript/TypeScript 和 Java。我的开发团队不使用 C#。
    • 是的,我对 Java 语法感到困惑。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-27
    • 1970-01-01
    • 2015-04-18
    • 2018-01-22
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多