You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用GAPI对接Google Identity Services时如何获取用户资料

问题核心原因

你拿不到id_token不是scope配置错了,是用错了GIS的授权客户端:

  • initTokenClient是专门用来获取「仅调用Google API用的access_token」的模式,这个模式设计上就不会返回id_token,哪怕你加了openid profile email scope也没用。
  • 你之前尝试调用plus接口失败是正常的,Google Plus API早在2020年就已经全量下线,所有相关请求都会被拒绝。

两种可行解决方案,选一个就行

方案1:走授权码模式拿id_token(官方推荐,无需额外接口调用)

把你现在用的tokenClient换成codeClient走OAuth2授权码流程,授权完成后会直接返回id_token,解码就能拿到姓名、邮箱信息,同时完全兼容你现有的gapi日历接口调用逻辑,改动最小。
修改步骤:

  1. 去Google Cloud控制台的OAuth2客户端配置页,把你当前页面的完整地址加到「已授权重定向URI」列表里。
  2. 替换原来的tokenClient初始化逻辑,核心代码参考:
// 替换原来的initTokenClient部分
let codeClient;
await new Promise((resolve, reject) => {
  try {
    codeClient = google.accounts.oauth2.initCodeClient({
      client_id: 'YOUR_CLIENT_ID',
      scope: 'openid profile email https://www.googleapis.com/auth/calendar.readonly',
      redirect_uri: window.location.origin + window.location.pathname,
      callback: async (authResponse) => {
        if (authResponse.error) return reject(authResponse);
        // 解析返回的id_token,直接拿用户信息
        const payload = JSON.parse(atob(authResponse.id_token.split('.')[1]));
        // payload.name就是用户姓名,payload.email就是用户邮箱
        console.log('用户信息:', payload.name, payload.email);

        // 用授权码换access_token,自动注入到gapi.client,不影响你原来的日历调用逻辑
        const tokenRes = await fetch('https://oauth2.googleapis.com/token', {
          method: 'POST',
          headers: {'Content-Type': 'application/x-www-form-urlencoded'},
          body: new URLSearchParams({
            code: authResponse.code,
            client_id: 'YOUR_CLIENT_ID',
            redirect_uri: window.location.origin + window.location.pathname,
            grant_type: 'authorization_code'
          })
        });
        const tokens = await tokenRes.json();
        gapi.client.setToken(tokens);
        resolve();
      }
    });
    resolve();
  } catch (err) {
    reject(err);
  }
});

// 原来触发授权的位置,把requestAccessToken替换成requestCode即可
codeClient.requestCode();
  1. 把你代码里加载plus v1 discovery文档的代码删掉,服务已下线,加载了也没用还会抛错。

方案2:保留现有access_token模式,调用People API拿用户信息

如果你不想改现有授权逻辑,直接用你已经拿到的access_token调用People API拿用户信息即可,不需要id_token。
注意点:

  1. scope里补充两个API权限:https://www.googleapis.com/auth/userinfo.profile、https://www.googleapis.com/auth/userinfo.email,不要只写openid对应的短scope。
  2. 删掉plus相关的加载逻辑,只保留people v1的discovery文档加载。
  3. 拿到access_token之后调用people/me接口,必须指定personFields参数,否则不会返回有效数据,核心代码参考:
// 授权成功后调用
const userRes = await gapi.client.people.people.get({
  resourceName: 'people/me',
  personFields: 'names,emailAddresses'
});
// 姓名:userRes.result.names[0].displayName
// 邮箱:userRes.result.emailAddresses[0].value
console.log(userRes.result);

额外注意事项
  • 前端直接base64解码id_token拿到的用户信息仅适合做页面展示,如果涉及后端鉴权逻辑,必须在服务端校验id_token的签名,避免伪造请求。
  • 老版oauth2 v2的userinfo接口已经处于维护状态,新功能不再迭代,优先选上面两种方案。

内容的提问来源于stack exchange,提问作者Jon H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 08:31:00