执行日志:
内部authorize()函数------------------------
在readAuth2TokensFromFile()函数内部------------------------
从文件中读取令牌时出错:./ credentials / token.json 在getNewTokensFromGoogleCLI()函数内部------------------------
通过访问以下(Google登录)URL:https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&scope= ...
来授权此应用 在getAnswerOn(question)函数内部------------------------
...正在等待Google CLI的响应...
此函数调用readLineInterface的问题:
/**
* @param {string} query The question to ask.
*/
function getAnswerOn(question) {
console.log("inside getAnswerOn(question) function ------------------------");
return new Promise((resolve) => {
//https://millermedeiros.github.io/mdoc/examples/node_api/doc/readline.html
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question(question, (answer) => {
console.log("Answer received succesfully!");
rl.close();
process.stdin.destroy();
resolve(answer);
});
})
}
OAuth2Authorizer.js文件的完整源代码:
//Based on https://stackoverflow.com/questions/54882145/is-there-an-async-await-node-js-google-auth-module
//OAuth2Authorizer with Promises
'use strict'
const fs = require('fs');
const readline = require('readline');
const functions = require('firebase-functions');
const { google } = require('googleapis');
//Go to the Google Cloud Dashboard: APIs and Services/ Credentials panel:
//https://console.cloud.google.com/apis/credentials
//OAuth2 Client Credentials (Other):
const KEY = require("./credentials/oauth2.key.json").web;
/**
* Create a new OAuth2 client with the configured keys.
* https://github.com/googleapis/google-api-nodejs-client
*/
const oauth2Client = new google.auth.OAuth2(
KEY.client_id,
KEY.client_secret,
KEY.redirect_uris[0]
);
function getOAuth2Client() {
console.log("inside getOAuth2Client ----------------------------");
return oauth2Client
}
/**
* reading Tokens from a file:
* @param {string} path Path to a JSON file where the tokens is stored in.
*/
function readAuth2TokensFromFile(path) {
console.log("inside readAuth2TokensFromFile() function ------------------------");
return new Promise((resolve, reject) => {
try {
resolve(JSON.parse(fs.readFileSync(path).toString()));
} catch (error) {
console.log("Error reading Tokens from a file:" + path);
resolve(undefined)
}
})
}
/**
* @param {string} query The question to ask.
*/
function getAnswerOn(question) {
console.log("inside getAnswerOn(question) function ------------------------");
return new Promise((resolve) => {
//https://millermedeiros.github.io/mdoc/examples/node_api/doc/readline.html
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question(question, (answer) => {
console.log("Answer received succesfully!");
rl.close();
process.stdin.destroy();
resolve(answer);
});
})
}
/**
* Get and store new token after prompting for user authorization, and then
* execute the given callback with the authorized OAuth2 client.
* @param {OAuth2Client} oAuth2Client The OAuth2 client to get token for.
* @param {string[]} scopes Scopes to get authorization for.
* @param {string} tokenFilePath Path to a JSON file to store the tokens in.
* @returns {OAuth2Client} terurns updated oAuth2Client
*/
function getNewTokensFromGoogleCLI(oAuth2Client, scopes, tokenFilePath) {
console.log("inside getNewTokensFromGoogleCLI() function ------------------------");
return new Promise((resolve, reject) => {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: scopes,
});
console.log('Authorize this app by visiting this (Google login) url: ', authUrl);
getAnswerOn("Enter the long code from that page here:").then(answer => {
try {
console.log("trying to get new token (before getToken) ------------------")
oAuth2Client.getToken(answer, (err, tokens) => {
if (!err) {
// Now tokens contains an access_token and an optional refresh_token. Save them.
oauth2Client.setCredentials(tokens);
resolve(oauth2Client) //return updated oauth2Client <-----------------------------
try {
// Store the token to disk for later program executions
fs.writeFileSync(tokenFilePath, JSON.stringify(tokens));
console.log('Token stored to', tokenFilePath);
} catch (error) {
console.error("Error while storing tokens in a file", error);
reject(new functions.https.HttpsError(error.code, error.message));
}
} else {
console.error('Error in oAuth2Client.getToken() function', err);
reject(new functions.https.HttpsError(err.code, err.message));
}
})
} catch (error) {
console.error('Error while trying to retrieve access token', error);
reject(new functions.https.HttpsError(error.code, error.message));
}
})
})
}
function authorize(key, scopes, tokenPath) {
console.log("inside authorize() function ------------------------");
return new Promise((resolve, reject) => {
try {
let REQ_SCOPES = scopes;
if (Array.isArray(scopes)) {
REQ_SCOPES = scopes.join(" "); //convert an array to the string
}
/*
* Create a new OAuth2 client with the configured keys.
* https://github.com/googleapis/google-api-nodejs-client
*/
const oauth2Client = new google.auth.OAuth2(
key.client_id,
key.client_secret,
key.redirect_uris[0]
);
readAuth2TokensFromFile(tokenPath).then(tokens => {
if (tokens) {
oauth2Client.setCredentials(auth2tokensTokens);
resolve(oauth2Client);
} else {
getNewTokensFromGoogleCLI(oauth2Client, REQ_SCOPES, tokenPath).then(updatedOAauth2Client => {
resolve(updatedOAauth2Client)
})
}
})
} catch (error) {
console.error('Error while getting a new oauth2Client from key: ', error);
reject(new functions.https.HttpsError(error.code, error.message));
}
})
}
//Use: const { authorize } = require('./OAuth2Authorizer.js');
exports.authorize = authorize;
答案 0 :(得分:1)
Oauth2工作应用程序的方式需要请求用户权限才能访问其数据。为此,我们向他们显示同意书。您的脚本告诉您
console.log('Authorize this app by visiting this (Google login) url: ', authUrl);
getAnswerOn("Enter the long code from that page here:").then(answer => {
在这里看到
通过访问以下URL(Google登录)授权此应用:https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&scope= ...
获取它为您提供的完整URL。将其放在网络浏览器中,表示同意访问,它将为您提供授权码。取回此代码,并将其放在等待它的应用程序中。
您的应用程序不会挂起,等待您响应其请求。