Not able to watch Admin Users Directory using `google-admin-sdk`

南楼画角 提交于 2020-11-24 22:48:04

问题


I am trying to connect to the G-Suite's User directory using the google-admin-sdk. I am using an API Key for authorization and I am not able to reach a successful execution.

Here is the code snippet that I'm using:

import { google } from 'googleapis';
import uuid from 'uuid/v4';

const API_KEY = 'my api key goes here';

google.admin({
  version: 'directory_v1',
  auth: API_KEY
}).users.list({
    customer: 'my_customer',
    maxResults: 10,
    orderBy: 'email',
  }, (err, res: any) => {
    if (err) { return console.error('The API returned an error:', err.message); }

    const users = res.data.users;
    if (users.length) {
      console.log('Users:');
      users.forEach((user: any) => {
        console.log(`${user.primaryEmail} (${user.name.fullName})`);
      });
    } else {
      console.log('No users found.');
    }
  });

Output:

Login Required

Can someone tell me what I am doing wrong here? Also, how do I proceed further for listening to the events emitted by the Google API?

---UPDATE---

Here is the snippet that works for me now:

import { JWT } from 'google-auth-library';
import { google } from 'googleapis';

// Importing the serivce account credentials
import { credentials } from './credentials';

const scopes = ['https://www.googleapis.com/auth/admin.directory.user'];
const adminEmail = 'admin_account_email_address_goes_here';
const myDomain = 'domain_name_goes_here';

async function main () {
  const client = new JWT(
    credentials.client_email,
    undefined,
    credentials.private_key,
    scopes,
    adminEmail
  );
  await client.authorize();
  const service = google.admin('directory_v1');

  const res = await service.users.list({
    domain: myDomain,
    auth: client
  });
  console.log(res);
}

main().catch(console.error);

--- Bonus Tip --- If you face any Parse Errors while using other methods of the directory, remember to JSON.stringify the request body. For example, on the admin.users.watch method:

// Watch Request
const channelID = 'channel_id_goes_here';
const address = 'https://your-domain.goes/here/notifications';
const ttl = 3600; // Or any other TTL that you can think of
const domain = 'https://your-domain.goes';

const body = {
  id: channelID,
  type: 'web_hook',
  address,
  params: {
    ttl,
  },
};

// Remember to put this in an async function
const res = await service.users.watch({
  domain,
  customer: 'my_customer',
  auth: client, // get the auth-client from above
  event: 'add'
}, {
  headers: {
    'Content-Type': 'application/json'
  },
  // This is the important part
  body: JSON.stringify(body),
});

回答1:


As you can see in the official documentation, every request sent "to the Directory API must include an authorization token". In order to authorize your request, you have to use OAuth 2.0.

You are providing an API key instead, which is not appropriate for this process. API keys are usually used for accessing public data, not users' private data as in your current situation.

You should follow the steps provided in the Node.js Quickstart instead:

  • First, obtain client credentials from the Google API Console.
  • Second, authorize the client: obtain an access token after setting the user credentials and the appropriate scopes (a process accomplish in functions authorize and getNewToken in the Quickstart).
  • Finally, once the client is authorized, call the API (function listUsers).

Update:

If you want to use a Service Account for this, you will have to follow these steps:

  • Grant domain-wide delegation to the Service Account by following the steps specified here.
  • In the Cloud console, create a private key for the Service Account and download the corresponding JSON file. Copy it to your directory.
  • Use the Service Account to impersonate a user who has access to this resource (an Admin account). This is achieved by indicating the user's email address when creating the JWT auth client, as indicated in the sample below.

The code could be something along the following lines:

const {google} = require('googleapis');
const key = require('./credentials.json'); // The name of the JSON you downloaded

const jwtClient = new google.auth.JWT(
  key.client_email,
  null,
  key.private_key,
  ['https://www.googleapis.com/auth/admin.directory.user'],
  "admin@domain" // Please change this accordingly
);

// Create the Directory service.
const service = google.admin({version: 'directory_v1', auth: jwtClient});

service.users.list({
  customer: 'my_customer',
  maxResults: 10,
  orderBy: 'email',
}, (err, res) => {
  if (err) return console.error('The API returned an error:', err.message);

  const users = res.data.users;
  if (users.length) {
    console.log('Users:');
    users.forEach((user) => {
      console.log(`${user.primaryEmail} (${user.name.fullName})`);
    });
  } else {
    console.log('No users found.');
  }
});

Reference:

  • Directory API: Authorize Requests
  • Directory API: Node.js Quickstart
  • Delegate domain-wide authority to your service account
  • Google Auth Library for Node.js

I hope this is of any help.



来源:https://stackoverflow.com/questions/60091248/not-able-to-watch-admin-users-directory-using-google-admin-sdk

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!