UPDATE2:我重新审视了这个问题,并通过仔细遵循下面链接的 doco 解决了这个问题。但首先,对于那些正在为此苦苦挣扎的人来说,你是一个很好的伙伴。谷歌的doco版本太多了,令人困惑!您是否在 html 中包含平台.js或客户端.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/listenershttps://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
这个问题相当古老,但是当谷歌搜索".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||(delete c.access_token,delete c.scope);return 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)));
getAuthResponse() 对象
{"token_type":"持票人","login_hint":"
<Huge mess of letters>
","expires_in":2112,"id_token":"<insert your ridiculously long string here>
",...}
getAuthResponse(true) 对象
{"token_type":"持票人","access_token":"
<an actual access token goes here>
","范围":"<whatever scopes you have authorized>
","login_hint":"<another mess of letters>
","expires_in":2112,"id_token":"<Insert your ridiculously long string here>
",...}
想出了解决这个问题的方法。事实证明,如果我们不在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'
})