GoogleUser.getAuthResponse()不包含access_token

Sim*_*son 17 google-api google-api-client google-drive-api

更新2:我重新审视了这个问题,并通过仔细遵循下面链接的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;
}
Run Code Online (Sandbox Code Playgroud)

我猜getAuthResponse一旦准备好就会以某种方式提供回调,但我无法看到API中的位置. https://developers.google.com/identity/sign-in/web/reference

Jhe*_*cht 28

我知道这个问题相当陈旧,但是当谷歌搜索".getAuthResponse()没有access_token"时,它首先出现,"这就是我在这里的方式.

所以对于你们2016年(也许更晚)的人来说,这就是我所发现的

有一个秘密的论点.getAuthResponse,没有记录我找到的任何地方.如果您要在应用中运行以下内容

console.log(gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse);
Run Code Online (Sandbox Code Playgroud)

你会看到你得到以下内容(从我的控制台复制/粘贴)

function(a){if(a)return this.hg; a = .HE; var c = .rf(this.hg);! a.Ph || a.dL || a.Lg ||(删除c. access_token,delete c.scope); return 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)));
Run Code Online (Sandbox Code Playgroud)

getAuthResponse()对象

{"token_type":"Bearer","login_hint":" <Huge mess of letters>","expires_in":2112,"id_token":" <insert your ridiculously long string here>",...}

getAuthResponse(true)对象

{"token_type":"Bearer","access_token":" <an actual access token goes here>","scope":" <whatever scopes you have authorized>","login_hint":" <another mess of letters>","expires_in":2112,"id_token":" <Insert your ridiculously long string here>",...}

希望这可以帮助你们!

  • 我爱你,在开发人员的开发方式!挣扎了几个小时才得到令牌,最后一个解决方案有效. (5认同)
  • 我也爱你.当然,开发人员以开发人员的方式. (3认同)
  • 我爱你3,在开发人员的开发方式! (2认同)

swa*_*hra 15

想出了解决方案.事实证明,如果我们不提供登录范围配置gapi.auth2.init它不返回的access_token getAuthResponse.请拨打下面给出的gapi.auth2.init,并提供access_token.

gapi.auth2.init({
  client_id: <googleClientID>,
  'scope': 'https://www.googleapis.com/auth/plus.login'
})
Run Code Online (Sandbox Code Playgroud)