簡體   English   中英

使用Node中的googleapis包交換訪問令牌的授權碼

[英]Exchanging authorization code for access token with googleapis package in Node

我正在嘗試為需要 googledrive 訪問權限的服務器端 NodeJS 應用程序實現谷歌登錄,但無法獲取“googleapis”谷歌對象來交換實際訪問令牌的授權代碼。

有關於我想在這里做什么的 google 文檔,但是第 7 步,這是我卡住的地方,是用 Java 和 Python 描述的,因此 NodeJS google 對象不存在。 我也遵循了此處的 nodeJS 快速入門,但許多身份驗證步驟是不同的。 也就是說,我無法以相同的方式創建google.auth.OAuth2對象,因為我的應用程序的憑據與示例的格式不同(它們沒有重定向 uri)

這是我得到它的地方:

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



formAuthClient('<PastedAuthCodeFromFrontEnd>');

async function formAuthClient(code) {
  // reads credentials from file
  const credentials = await readFile('./client_secret.json').then(JSON.parse);

  // cannot read redirect_uris like in NodeJS quickstart because these do not exist. 
  // Also, no credentials.installed, it's credentials.web
  const { client_secret, client_id } = credentials.web;
  const oAuth2Client = new google.auth.OAuth2( // form authObject
    client_id, client_secret
  );
  console.log(oAuth2Client);

  const token = await oAuth2ClientGetToken(oAuth2Client, code).catch(console.err);
  oAuth2Client.setCredentials(token);
  return oAuth2Client;
}


// just an async wrapper for fs.readFile
function readFile(file) {
  return new Promise((resolve, reject) => {
    fs.readFile(file, (err, content) => {
      if (err) reject(err);
      resolve(content);
    });
  })
}
// just an async wrapper for oAuth2Client.getToken
function oAuth2ClientGetToken(oAuth2Client, code) {
  return new Promise((resolve, reject) => {
    oAuth2Client.getToken(code, (err, token) => { // errors out here
      if (err) reject(err);
      resolve(token);
    });
  });
}

運行此代碼首先打印 oAuth2Client 對象,然后給我以下錯誤:


OAuth2Client {
  _events: [Object: null prototype] {},
  _eventsCount: 0,
  _maxListeners: undefined,
  transporter: DefaultTransporter {},
  credentials: {},
  certificateCache: {},
  certificateExpiry: null,
  certificateCacheFormat: 'PEM',
  refreshTokenPromises: Map {},
  _clientId: '<probablySecretClientID>.apps.googleusercontent.com',
  _clientSecret: '<defSecretClientSecret>',
  redirectUri: undefined,
  eagerRefreshThresholdMillis: 300000
}


(node:16186) UnhandledPromiseRejectionWarning: Error: invalid_grant
    at Gaxios.request (/home/miko/node/clouds/api/node_modules/gaxios/build/src/gaxios.js:70:23)
    at processTicksAndRejections (internal/process/task_queues.js:89:5)
    at async OAuth2Client.getTokenAsync (/home/miko/node/clouds/api/node_modules/google-auth-library/build/src/auth/oauth2client.js:119:21)
(node:16186) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:16186) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code

理想情況下,我希望 top 函數返回一個完全經過身份驗證的客戶端對象,以后我可以用它來訪問谷歌驅動器 API

我在這里想出了一個解決方案https://github.com/googleapis/google-api-nodejs-client/issues/1951

對於我之后的所有事情 - 解決先決條件如果您與我有相同的設置,您不是在前端瀏覽器反應代碼中而是在后端設置中執行令牌交換。 我做了以下似乎解決了這個問題的事情。

1> 在 Google Cloud 平台中添加輔助主機名/端口 > APIs& Services > Credentials>(您的 oauth ClientID。)> Authorized JavaScript origins。 使用您的網絡應用程序 URI。

例如,如果你有 localhost:3000 服務你的反應代碼和 localhost:3002。 你需要同時做廣告。 這也適用於您的生產設置。

2> 授權碼只能使用一次。 一旦你使用它,如果你沒有存儲刷新令牌/訪問令牌。 您需要再次要求用戶進行身份驗證。 它給出了完全相同的信息。

3> 持有授權令牌的時間似乎有時間限制。 谷歌可以比我更好地回答這個問題,但是我注意到如果我將有效的合法授權令牌存儲一個多小時,我會得到同樣的錯誤,並且它給了我與上面相同的消息。

我的建議是發回比數據更好的錯誤:{ error: 'invalid_grant', error_description: 'Bad Request' },

由於上述所有情況似乎都導致了相同的錯誤。 我很難調試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM