Google 身份验证挂起等待响应
Google auth hanging waiting for response
执行日志:
inside authorize() function ------------------------
inside readAuth2TokensFromFile() function ------------------------
Error reading Tokens from a file:./credentials/token.json
inside getNewTokensFromGoogleCLI() function ------------------------
Authorize this app by visiting this (Google login) url: https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&scope=...
inside getAnswerOn(question) function ------------------------
...等待来自 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
//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;
Oauth2 的工作方式您的应用程序需要请求用户的许可才能访问他们的数据。为此,我们向他们出示同意书。您的脚本告诉您
console.log('Authorize this app by visiting this (Google login) url: ', authUrl);
getAnswerOn("Enter the long code from that page here:").then(answer => {
如图所示
Authorize this app by visiting this (Google login) url: https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&scope=...
充分利用它给你的URL。把它放在网络浏览器中同意访问,它会给你一个授权码。取回此代码并将其放置在等待它的应用程序中。
您的应用程序没有挂起,它正在等待您响应它的请求。
执行日志:
inside authorize() function ------------------------
inside readAuth2TokensFromFile() function ------------------------
Error reading Tokens from a file:./credentials/token.json inside getNewTokensFromGoogleCLI() function ------------------------
Authorize this app by visiting this (Google login) url: https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&scope=...
inside getAnswerOn(question) function ------------------------
...等待来自 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
//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;
Oauth2 的工作方式您的应用程序需要请求用户的许可才能访问他们的数据。为此,我们向他们出示同意书。您的脚本告诉您
console.log('Authorize this app by visiting this (Google login) url: ', authUrl);
getAnswerOn("Enter the long code from that page here:").then(answer => {
如图所示
Authorize this app by visiting this (Google login) url: https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&scope=...
充分利用它给你的URL。把它放在网络浏览器中同意访问,它会给你一个授权码。取回此代码并将其放置在等待它的应用程序中。
您的应用程序没有挂起,它正在等待您响应它的请求。