如何通过一键登录流程将 Google API 客户端用于 JavaScript?

How to use the Google API client for JavaScript with a One-Tap sign in flow?

我正在使用 Google One-Tap sign in to authenticate users, and after the user is authenticated I get an access token. I know that I can use this access token in order to work with the Google API client for JavaScript ("GAPI")。但是我找不到使用此访问令牌使用 GAPI 的任何方法。

假设我已经有一个登录用户,有什么方法可以使用 GAPI 吗?

我想做的是在使用一键式身份验证进行身份验证并同意一次日历后访问用户日历。

首先:
无法使用 [=] 返回的响应来“验证”google JS api 客户端89=] 签到.

幸运的是,我们不需要使用 gapi JS 客户端进行身份验证,因为我们使用了一个名为 gapi.auth2.authorize!

的便捷函数

gapi客户端如何授权

首先阅读 docs 并理解他们的警告很重要:

Do not use this method alongside the recommended gapi.auth2.init and signIn flow. These are two distinct behaviors (Authorization for gapi.auth2.authorize vs Authentication for gapi.auth2.init/signIn) and will have unexpected issues if used within the same application.

现在的问题是如何完全避免init/signIn方法。

步骤 1
将用户登录到 Google One-Tap 登录。

步骤 2
加载 gapi 客户端:window.gapi.load('client')

步骤 3
将 Google One-Tap 返回的 credential.id(电子邮件地址)作为 login_hint 授权调用中的参数。这将预选帐户,我们可以尝试不显示任何新登录 pop-up(提示)。

示例:

gapi.auth2.authorize({
  client_id,
  prompt: 'none',
  response_type: 'permission', // Access Token.
  scope: 'CALENDAR_SCOPE',
  login_hint: credential.id
}, function(result) {})

使用提示:'none',您可以尝试在没有任何 UI 的情况下获取令牌。这对于检查您是否需要显示授权按钮很有用,并且在调用日历 API 以获取新令牌之前也很有用。

第 4 步
在调用 gapi.client.calendar 之前,我们需要仅使用日历 [=] 初始化 client 19=].

gapi.client.init({discoveryDocs})

这是最棘手的部分,任何地方都没有正确记录!我们唯一可以从 api.client.init() documentation 中检索到的是以下行:

If OAuth client ID and scope are provided, this function will load the gapi.auth2 module to perform OAuth

这基本上意味着:只要您提供 clientIDscope gapi.client.init 就会尝试并启动传统的身份验证方法。
在我们的例子中:我们不需要传递 clientIDscope 因为我们已经在 步骤 3.

中完成了此操作

那么客户端怎么知道要初始化哪个模块呢? → 仅传递您要使用的模块的 discoveryDocs!在这种情况下,日历 discoveryDocs.

第 5 步
大功告成!您可以使用例如提出请求gapi.client.calendar.events.list()


完整示例

可以在下面找到完整的代码示例:

const config =  {
  response_type: 'permission',
  scope: 'CALENDAR_SCOPE',
  client_id: clientId,
  login_hint: credential.id,
  promt: 'none',
}
gapi.auth2.authorize(config, function(response) {
  // No need to `setToken`, it's done for you by auth2.
  let calConfig = {discoveryDocs} // only of google calendar
  window.gapi.client.init(calConfig).then(function() {
    // then execute a calendar call:
    window.gapi.client.calendar.events.list({'calendarId': 'primary'})
  })
})