至少到今年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调试器中发送的请求,它看起来与我正在做的相似。
答案 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();