1

我正在尝试在经过身份验证的 Google 帐户下列出企业。我已经完成了 Oauth2 流程并获得了包含access_token, id_token,refresh_token and expiry_date

现在,当我尝试在该帐户下列出企业时,我不断得到Unauthorized Error.

以下是我的流程:

initOAuth2Client() {
    return new google.auth.OAuth2(
        process.env.GOOGLE_CLIENT_ID,
        process.env.GOOGLE_CLIENT_SECRET,
        process.env.GOOGLE_REDIRECT_URL
    );
}

//Authorization Code
async authenticateAgainstGoogleMyBusiness() {
    let oauth2Client = module.exports.initOAuth2Client();
    const scopes = [
        'https://www.googleapis.com/auth/business.manage',
        'https://www.googleapis.com/auth/userinfo.profile'
    ];
    const state = ....
    const url = oauth2Client.generateAuthUrl({
        access_type: 'offline',
        scope: scopes,
        state: state,
        prompt: 'consent'
    });
}

然后对于我的 Oauth 回调处理程序,我有这个

async googleOAuthCallbackHandler(req, res) {
    let oauth2Client = module.exports.initOAuth2Client();
    let { code, state } = req.query;
    const oauth2Client = module.exports.initOAuth2Client();
    const { tokens } = await oauth2Client.getToken(code);
    //this is where I saved the tokens exactly as received.
}

  async fetchGoogleMyBusinessAccounts() { 
   let {access_token} = fetchTokenFromDatabase(); //This is how I retrieved the access tokens saved by the previous function.

    console.log(`Fetching GMB Accounts`);
    let accountsUrls = `https://mybusinessaccountmanagement.googleapis.com/v1/accounts`;
    try {
        let headers = {
            'Authorization': `Bearer ${access_token}`
        }
        let response = axios.get(accountsUrls, {
            headers: headers
        });
        let data = response.data;
        console.log(`GMB Accounts response = ${JSON.stringify(data, null, 2)}`);
    } catch (e) {
        console.log('Error retrieving GMB Accounts:Full error below:');
        console.log(e); //I keep getting Unauthorized even though I authorized the process on the oauth consent screen
    }
}

我怎样才能解决这个问题?

4

1 回答 1

1

我认为您应该查看Google 驱动器的示例我不知道为什么 Google 不发布所有 API 的示例但他们没有。我通过稍微改变谷歌驱动器的样本来把它放在一起。我现在没有安装节点,但这应该是关闭的

如果您有任何问题,请告诉我,我可以尝试帮助您调试它们。

const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');

// If modifying these scopes, delete token.json.
const SCOPES = ['https://www.googleapis.com/auth/business.manage'];
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
const TOKEN_PATH = 'token.json';

// Load client secrets from a local file.
fs.readFile('credentials.json', (err, content) => {
  if (err) return console.log('Error loading client secret file:', err);
  // Authorize a client with credentials, then call the Google Drive API.
  authorize(JSON.parse(content), listFiles);
});

/**
 * Create an OAuth2 client with the given credentials, and then execute the
 * given callback function.
 * @param {Object} credentials The authorization client credentials.
 * @param {function} callback The callback to call with the authorized client.
 */
function authorize(credentials, callback) {
  const {client_secret, client_id, redirect_uris} = credentials.installed;
  const oAuth2Client = new google.auth.OAuth2(
      client_id, client_secret, redirect_uris[0]);

  // Check if we have previously stored a token.
  fs.readFile(TOKEN_PATH, (err, token) => {
    if (err) return getAccessToken(oAuth2Client, callback);
    oAuth2Client.setCredentials(JSON.parse(token));
    callback(oAuth2Client);
  });
}

/**
 * Get and store new token after prompting for user authorization, and then
 * execute the given callback with the authorized OAuth2 client.
 * @param {google.auth.OAuth2} oAuth2Client The OAuth2 client to get token for.
 * @param {getEventsCallback} callback The callback for the authorized client.
 */
function getAccessToken(oAuth2Client, callback) {
  const authUrl = oAuth2Client.generateAuthUrl({
    access_type: 'offline',
    scope: SCOPES,
  });
  console.log('Authorize this app by visiting this url:', authUrl);
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  });
  rl.question('Enter the code from that page here: ', (code) => {
    rl.close();
    oAuth2Client.getToken(code, (err, token) => {
      if (err) return console.error('Error retrieving access token', err);
      oAuth2Client.setCredentials(token);
      // Store the token to disk for later program executions
      fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
        if (err) return console.error(err);
        console.log('Token stored to', TOKEN_PATH);
      });
      callback(oAuth2Client);
    });
  });
}

/**
 * Lists the names and IDs of up to 10 files.
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */
function listFiles(auth) {
  const service = google.mybusinessaccountmanagement({version: 'v1', auth});
  service.accounts.get({
    pageSize: 10,
    fields: '*',
  }, (err, res) => {
    if (err) return console.log('The API returned an error: ' + err);
    const accounts= res.accounts;
    if (accounts.length) {
      console.log('accounts:');
      accounts.map((account) => {
        console.log(`${account.name} (${account.id})`);
      });
    } else {
      console.log('No files found.');
    }
  });
}

来自评论

让我们看看评论中的这个错误消息。

代码:429,错误:[ {消息:“配额指标“请求”超出配额,并限制消费者“项目编号:xxxxx”的服务“mybusinessaccountmanagement.googleapis.com”的“每分钟请求数”。”,域:“全球” ,原因:'rateLimitExceeded' } ] }

当你在谷歌云平台上创建你的项目时,你必须启用你要使用的 api。

在此处输入图像描述

如果您返回并通过左侧的(提示管理按钮)检查它,则会有关于配额的注释

在此处输入图像描述

每个 api 在启用时都有一个默认配额。此 api 的默认配额是

在此处输入图像描述

配额是控制你可以向 api 发出多少请求的东西。谷歌限制了我们,因为他们希望我们所有人都能使用 api。他们不希望只有一个应用程序淹没系统。

如您所见,此 api 的默认配额为 0,这就是为什么您已经超出限制而没有发出任何请求的原因。

在这个页面的顶部有一条注释说

在 IAM & admin 中的配额页面上请求更多配额限制或查看其他服务的配额。

经过大量挖掘后,我设法在页面的最底部找到了一个指向请求额外配额使用限制的表单的链接,有一行说

如果您需要更高的限制,您可以提交标准配额请求。

提交表格。我不知道您需要多长时间才能获得配额延期。

于 2021-10-29T13:26:04.367 回答