UPDATE2:我重新审视了这个问题,并通过仔细关注下面链接的doco解决了这个问题。但首先,对于那些正在努力解决这个问题的人来说,你们的团结良好。谷歌有很多版本的doco令人困惑!你在html中包含了platform.js或client.js吗?你加载gapi.auth或gapi.auth2?你使用gapi.auth2.render或gapi.auth.authorize,还是gapi.auth2.init等等。
返回access_token的方式(截至本文日期)在下面链接。我设法通过使用platform.js仔细遵循指南和参考来实现这一点。然后使用gapi.load('drive',callback)动态加载其他库,例如client.js.
https://developers.google.com/identity/sign-in/web/listeners https://developers.google.com/identity/sign-in/web/reference
====最初的繁荣问题====
更新1: 我已经更新了代码示例,以便对googleUser对象进行递归搜索。至少这不应该在随后的库中中断。
下面是一个代码片段来处理Google gapi.auth2.AuthResponse对象中的access_token不在顶层的问题...它被隐藏:(在对象的深处!
所以它是可以检索的,但不是顶级的!!我注意到它似乎是一个计时问题......一旦应用程序在后续检查中运行了一段时间,它确实包含顶级访问令牌!!
var authResponse = _.googleUser.getAuthResponse();
_.id_token = authResponse.id_token; // Always exists
// access_token should also be a param of authResponse
if (authResponse.access_token) {
debug("Worked this time?");
_.access_token = authResponse.access_token;
} else {
// !!! Internal object access !!!
debug("Attempt to get access token from base object.");
_.access_token = _.objRecursiveSearch("access_token", _.googleUser);
if (_.access_token) {
debug("Access token wasn't on authResponse but was on the base object, WTF?");
} else {
debug("Unable to retrieve access token.");
return false;
}
}
_.objRecursiveSearch = function(_for, _in) {
var r;
for (var p in _in) {
if (p === _for) {
return _in[p];
}
if (typeof _in[p] === 'object') {
if ((r = _.objRecursiveSearch(_for, _in[p])) !== null) {
return r;
}
}
}
return null;
}
我猜测getAuthResponse会在它准备好后以某种方式提供回调,但我无法看到API中的位置。 https://developers.google.com/identity/sign-in/web/reference
答案 0 :(得分:22)
我知道这个问题相当陈旧,但是当谷歌搜索时,它首先出现。#getAuthResponse()没有access_token,"我就是这样来的。
所以对于你们2016年(也许是后来)的人来说,我发现了
.getAuthResponse
上有一个秘密论据,而我未找到 。如果您要在应用中运行以下内容
console.log(gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse);
你会看到你得到以下内容(从我的控制台复制/粘贴)
function(a){if(a)return this.hg; a = .HE; var c = .rf(this.hg);! a.Ph || a.dL | | a.Lg ||(删除c.access_token,删除c.scope);返回c}
这表明.getAuthResponse()
函数查找一个参数,据我所知,它甚至不检查它的值 - 它只是检查它是否存在然后返回整个对象。如果没有该功能,其余代码就会运行,我们可以非常清楚地看到它正在删除两个键:access_token
和scope
。
现在,如果我们使用和不使用参数调用此函数,我们可以检查输出中的差异。 (注意:我使用了JSON.stringify,因为尝试从浏览器控制台复制/粘贴对象导致了一些问题。)
console.log(JSON.stringify(gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse()));
console.log(JSON.stringify(gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse(true)));
{ " token_type":"承载&#34 ;, " login_hint":"
<Huge mess of letters>
&#34 ;, &#34; expires_in&#34;:2112, &#34; id_token&#34;:&#34;<insert your ridiculously long string here>
&#34;,...}
{ &#34; token_type&#34;:&#34;承载&#34 ;, &#34;&的access_token#34;:&#34;
<an actual access token goes here>
&#34 ;, &#34;范围&#34;:&#34;<whatever scopes you have authorized>
&#34 ;, &#34; login_hint&#34;:&#34;<another mess of letters>
&#34 ;, &#34; expires_in&#34;:2112, &#34; id_token&#34;:&#34;<Insert your ridiculously long string here>
&#34 ;, ...}
希望这可以帮助你们!
答案 1 :(得分:14)
找出解决方法。事实证明,如果我们不在 gapi.auth2.init 中提供登录范围配置,则它不会在 getAuthResponse 中返回access_token。请拨打下面给出的gapi.auth2.init,并且会出现access_token。
gapi.auth2.init({
client_id: <googleClientID>,
'scope': 'https://www.googleapis.com/auth/plus.login'
})