我想代表其他用户访问 Google Analytics Admin API。我从带有身份验证窗口弹出窗口的 Oauth2 对话框流中获得了有效的 oAuth2 访问令牌。
Google 提供新的 Cloud 客户端库 或更旧的 Google API 客户端库 来访问其服务。
谷歌然后说这里:
云客户端库是用于以编程方式访问云 API 的推荐选项(如果可用)
但是,这些较新的云库似乎不提供代表其他用户(不是我自己)访问的 OAuth2 身份验证。
例如,我想使用 Google Analytics Admin API。
我访问 Google Analytics Admin Cloud Client 库,文档告诉我通过从我的凭证区域下载 JSON 文件来进行身份验证(这仅在我访问我自己的服务时有效,但不能代表给定用户进行 API 调用)
// Instantiates a client using default credentials.
// TODO(developer): uncomment and use the following line in order to
// manually set the path to the service account JSON file instead of
// using the value from the GOOGLE_APPLICATION_CREDENTIALS environment
// variable.
// const analyticsAdminClient = new analyticsAdmin.AnalyticsAdminServiceClient(
// {keyFilename: "your_key_json_file_path"});
const analyticsAdminClient = new analyticsAdmin.AnalyticsAdminServiceClient();
// Calls listAccounts() method of the Google Analytics Admin API and prints
// the response for each account.
const [accounts] = await analyticsAdminClient.listAccounts();
然后我访问旧的 Analytics Admin 的 Google API 客户端库。
它支持 Oauth2 access_tokens ...但它首先说的是:
注意:Google 为此服务提供了多个库。该库处于维护模式,并将继续向拥有现有应用程序的用户开放。如果您正在构建新应用程序或对旧应用程序进行现代化改造,请改用 @google-analytics/admin。 @google-analytics/admin 库更快、更易于使用且维护得更好。
我想要更新更好的库,但是它们是否代表其他用户支持 Oauth2?
我知道我可以使用 Google Auth Library 获取 oAuth2 access_tokens。但我不知道如何使用这些令牌来授权较新的云库。
他们确实提供了 oauth2,只是没有提供示例,但我提供了。
// npm install googleapis@105 @google-cloud/[email protected] --save
// npm install @google-analytics/data
const fs = require('fs');
const path = require('path');
const process = require('process');
const {authenticate} = require('@google-cloud/local-auth');
const {google} = require('googleapis');
const {BetaAnalyticsDataClient} = require("@google-analytics/data");
// If modifying these scopes, delete token.json.
const SCOPES = ['https://www.googleapis.com/auth/analytics.readonly'];
// Token File Name
const TOKEN_FILE = 'token.json'
// 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 = path.join(process.cwd(), TOKEN_FILE);
const CREDENTIALS_PATH = 'C:\\Development\\FreeLance\\GoogleSamples\\Credentials\\Credentials.json';
/**
* Reads previously authorized credentials from the save file.
*
* @return {Promise<OAuth2Client|null>}
*/
async function loadSavedCredentialsIfExist() {
try {
const content = fs.readFileSync(TOKEN_PATH,{encoding:'utf8', flag:'r'});
const credentials = JSON.parse(content);
return google.auth.fromJSON(credentials);
} catch (err) {
return null;
}
}
/**
* Serializes credentials to a file compatible with GoogleAUth.fromJSON.
*
* @param {OAuth2Client} client
* @return {Promise<void>}
*/
async function saveCredentials(client) {
const content = fs.readFileSync(CREDENTIALS_PATH, {encoding:'utf8', flag:'r'});
const keys = JSON.parse(content);
const key = keys.installed || keys.web;
const payload = JSON.stringify({
type: 'authorized_user',
client_id: key.client_id,
client_secret: key.client_secret,
refresh_token: client.credentials.refresh_token,
});
await fs.writeFileSync(TOKEN_PATH, payload);
}
/**
* Load or request or authorization to call APIs.
*
*/
async function authorize() {
let client = await loadSavedCredentialsIfExist();
if (client) {
return client;
}
client = await authenticate({
scopes: SCOPES,
keyfilePath: CREDENTIALS_PATH,
});
if (client.credentials) {
await saveCredentials(client);
}
return client;
}
/**
* Runs a Google Analytics report
* For a given property id
*/
async function runReport(authClient ) {
// Imports the Google Analytics Data API client library.
const {BetaAnalyticsDataClient} = require('@google-analytics/data');
// Load the credentials.
const content = fs.readFileSync('token.json', {encoding:'utf8', flag:'r'});
const keys = JSON.parse(content);
const analyticsDataClient = new BetaAnalyticsDataClient(
{ credentials: keys}
);
var propertyId = '250796939';
// Runs a simple report.
async function runReport() {
const [response] = await analyticsDataClient.runReport({
property: `properties/${propertyId}`,
dateRanges: [
{
startDate: '2020-03-31',
endDate: 'today',
},
],
dimensions: [
{
name: 'city',
},
],
metrics: [
{
name: 'activeUsers',
},
],
});
console.log('Report result:');
response.rows.forEach(row => {
console.log(row.dimensionValues[0], row.metricValues[0]);
});
}
await runReport();
}
authorize().then(runReport).catch(console.error);