GoogleUser.getAuthResponse()不包含access_token

时间:2016-01-15 03:40:12

标签: google-api google-drive-api google-api-client

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

2 个答案:

答案 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_tokenscope

现在,如果我们使用和不使用参数调用此函数,我们可以检查输出中的差异。 (注意:我使用了JSON.stringify,因为尝试从浏览器控制台复制/粘贴对象导致了一些问题。)

console.log(JSON.stringify(gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse()));
console.log(JSON.stringify(gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse(true)));

getAuthResponse()对象

  

{   &#34; token_type&#34;:&#34;承载&#34 ;,   &#34; login_hint&#34;:&#34; <Huge mess of letters>&#34 ;,   &#34; expires_in&#34;:2112,   &#34; id_token&#34;:&#34; <insert your ridiculously long string here>&#34;,...}

getAuthResponse(true)对象

  

{   &#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'
})