gapi grantOfflineAccess access_code to refresh_token

时间:2017-09-05 14:35:57

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

至少到今年6月底(2017年)(我的用户是教师,所以不要在夏天访问我们的应用程序......)我有以下工作流程。< / p>

用户可以使用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中,当我使用与我的应用相同的范围并交换&#34;代码&#34;对于刷新令牌,我用

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

所以,显然Playground正在采取与我不同的方式。我已经查看了Chrome调试器中发送的请求,它看起来与我正在做的相似。

1 个答案:

答案 0 :(得分: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();