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

调用gapi.client.oauth2.userinfo.get()获取谷歌用户信息报错求助

问题解决:Google OAuth2隐式流调用userinfo.get()报错及获取完整用户信息方案

错误原因分析

你遇到的Error: arrayForEach was called with a non array value,本质是未正确加载OAuth2 Userinfo API的发现文档,导致gapi.client.oauth2.userinfo.get()方法内部调用逻辑异常。另外,即使解决这个错误,Userinfo接口也无法获取手机号和组织信息,必须改用Google People API才能拿到这些数据。

修正方案及代码调整

1. 启用正确的权限范围

取消注释你写的完整scopes,确保包含获取所有所需信息的权限:

const scopes = 'profile https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/user.phonenumbers.read https://www.googleapis.com/auth/people.readonly';
  • people.readonly:用于通过People API读取用户基本资料(包括组织信息)
  • user.phonenumbers.read:用于读取用户手机号
  • userinfo.email:用于读取用户邮箱

2. 修正API加载逻辑

确保只加载所需的People API发现文档(无需额外加载OAuth2 Userinfo,因为我们改用People API获取所有信息):

async function loadApis() {
    await gapi.client.load('https://www.googleapis.com/discovery/v1/apis/people/v1/rest');
    console.log('Finished loading People API.');
}

3. 重构用户信息获取函数

替换原来的loadUserInfo,改用People API的people.get方法,指定需要获取的字段(邮箱、手机号、组织信息):

async function loadUserInfo() {
    console.log(`Loading user info.`);
    try {
        // 获取当前授权用户的资料,指定需要的字段
        const response = await gapi.client.people.people.get({
            resourceName: 'people/me',
            personFields: 'emailAddresses,phoneNumbers,organizations'
        });
        
        const userData = response.result;
        console.log('用户完整信息:', userData);
        
        // 提取所需字段示例
        const email = userData.emailAddresses?.[0]?.value;
        const phone = userData.phoneNumbers?.[0]?.value;
        const company = userData.organizations?.[0]?.name;
        
        console.log('邮箱:', email);
        console.log('手机号:', phone);
        console.log('公司名称:', company);
    } catch (err) {
        console.error('获取用户信息失败:', err);
    }
}

4. 调整异步调用顺序

确保loadApis完成后再调用loadUserInfo,原代码中loadApis()没有await,会导致API未加载完成就调用接口:

callback: async (tokenResponse) => {
    console.log(`Token response:`, tokenResponse);
    access_token = tokenResponse.access_token;
    console.log(`Finished requesting access.`);

    await loadApis(); // 等待API加载完成
    await loadUserInfo();
},

完整修正后的代码

const apiKey = 'XXXXXX';
const clientId = 'XXXXXX';
// 启用完整权限范围
const scopes = 'profile https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/user.phonenumbers.read https://www.googleapis.com/auth/people.readonly';

let tokenClient;
let access_token;

const gapiLoad = async () => {
    await new Promise((resolve) => gapi.load('client', resolve));
    console.log(`Loaded gapi client.`);
}

const gisInit = async () => {
    tokenClient = google.accounts.oauth2.initTokenClient({
        client_id: clientId,
        scope: scopes,
        callback: async (tokenResponse) => {
            console.log(`Token response:`, tokenResponse);
            access_token = tokenResponse.access_token;
            console.log(`Finished requesting access.`);

            await loadApis();
            await loadUserInfo();
        },
    });
    console.log(`Loaded token client.`);
    await gapiLoad();
    await getToken();
}

gisInit();

async function loadApis() {
    await gapi.client.load('https://www.googleapis.com/discovery/v1/apis/people/v1/rest');
    console.log('Finished loading People API.');
}

async function loadUserInfo() {
    console.log(`Loading user info.`);
    try {
        const response = await gapi.client.people.people.get({
            resourceName: 'people/me',
            personFields: 'emailAddresses,phoneNumbers,organizations'
        });
        
        const userData = response.result;
        console.log('用户完整信息:', userData);
        
        const email = userData.emailAddresses?.[0]?.value;
        const phone = userData.phoneNumbers?.[0]?.value;
        const company = userData.organizations?.[0]?.name;
        
        console.log('邮箱:', email);
        console.log('手机号:', phone);
        console.log('公司名称:', company);
    } catch (err) {
        console.error('获取用户信息失败:', err);
    }
}

async function getToken() {
    await tokenClient.requestAccessToken();
}

额外注意事项

  • 确保你的Google Cloud项目中已经启用了People API(在Google Cloud控制台的API库中搜索启用)
  • 测试时注意用户账号是否有完善的手机号和组织信息(部分个人账号可能没有组织信息)

内容的提问来源于stack exchange,提问作者Jeff Fischer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 08:08:11