[英]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.