投稿者:佐々木 純平

弊社はHCL Notes/Domino(旧IBM Lotus Notes/Domino)から Google G Suiteへの移行作業を進めており、タスクの一つとして、Notesで管理していた社員マスターをG Suite上の情報も活用する形でGCP上で管理しようと考えています。そのためにG Suite上の情報を取得するプログラムをAdmin SDK公式ドキュメントを参考にNode.jsで組みましたが、いざプログラムを実行してみると、API(Admin SDK)使用時に必要なトークン取得の際に、管理者ユーザーによる認証フロー(画面でのクリック作業)が必要でした。
これをどうにか自動化できないかと試行錯誤していたところ、GCPのサービスアカウントを利用した認証方法の記事を参考に実装することができたので、今回はその方法をご紹介いたします。

## 目次

  1. 概要
  2. 環境設定
    2.1 GCPの環境設定
    2.2 G Suiteの環境設定
  3. プログラム開発
    3.1 処理の流れ
    3.2 確認事項
    3.3 実行
    3.4 ソースコード
  4. まとめ

## 1. 概要

Node.jsでAdmin SDKを使用し、ドメイン全体のG Suiteアカウント情報を取得します。
なお、Admin SDK使用時に必要なトークンの取得の際はサービスアカウントの情報を利用します。
必要なタスクと流れは以下となります。

  1. GCPの環境設定
  2. G Suiteの環境設定
  3. プログラム開発

## 2. 環境設定

2.1 GCPの環境設定

このトピックはGCPコンソールでの作業となります。
ここではプログラムで使用するAPIを有効化するとともに、API使用のためのサービスアカウントの作成を行います。作業項目と流れは以下の通りです。

  1. プロジェクトを作成し、Admin SDKを有効化
  2. サービスアカウントを作成し、クライアントID確認、キーを作成

2.1.1 プロジェクトを作成し、Admin SDKを有効化

  • プロジェクトの作成に関してはGCP公式ドキュメントをご覧ください。
  • APIとサービス>ライブラリでAdmin SDKを検索し、有効化します。

画像の説明

2.1.2 サービスアカウントを作成し、クライアントID確認、キーを作成

  • サービスアカウントの作成に関してはGCP公式ドキュメントをご覧ください。
  • IAMと権利>サービスアカウント>該当するサービスアカウントのアドレスをクリック>編集>サービスアカウントのステータス>「G Suiteドメイン全体の委任を有効にする」にチェックを入れ、内容を保存します。

画像の説明

  • クライアントIDを表示で必要情報を表示させます。

画像の説明

  • 表示されたサービスアカウントのクライアントIDとメールアドレスを控えておきます。(後の作業で必要となります)

画像の説明

  • 以下画面のようにサービスアカウントのキー(jsonファイル)を生成し、ファイル名をgsuite_admin_service_account.jsonに変更します。

画像の説明

2.2 G Suiteの環境設定

このトピックはG Site管理コンソールでの作業となります。
ここではドメイン全体の権限をGCPのサービスアカウントに委任します。作業項目は以下の通りです。

  1. ドメイン全体の権限をサービスアカウントに委任

2.2.1ドメイン全体の権限をサービスアカウントに委任

  • セキュリティ>詳細設定>APIクライアントアクセスを管理するで以下画像のような画面が表示されるので、赤枠の部分に下記載情報を入力して承認ボタンを押下します。

    • クライアント名 :2.1.2で控えたサービスアカウントのクライアントID
    • 1つ以上のAPIスコープ :必要なスコープ(今回はhttps://www.googleapis.com/auth/admin.directory.user)を指定

    ※Directory APIに関するその他スコープはこちらをご参照ください。


画像の説明

## 3. プログラム開発

3.1 処理の流れ

処理の流れは以下の通りです。
本来は、ドメインのG Suite管理者による認証フロー(画面でのクリック作業)を経てAPIトークンを取得してAPIコールを行いますが、今回のように権限を委任されたサービスアカウントの情報(gsuite_admin_service_account.json)を利用することで、そのフローをスキップすることが可能です。

  1. サービスアカウント情報(gsuite_admin_service_account.json)の読み込み
  2. 上記1を利用したクライアント認証
  3. APIをコールしアカウント情報を取得し出力

3.2 前提条件

実行前に以下の項目を確認してください。
なお、動作環境はwindows、Nodeはv10.16.3になります。 - gsuite_admin_service_account.jsonは同じディレクトリ内に保存されていること - 必要ライブラリのインストールが完了していること

3.3 実装

以下ソースコードのように実装しました。これを実行すると10件のアカウント情報(今回のプログラムではメールアドレスと名前のみ)が表示されます。21行目あたりのオプションを変更することで、表示数やソート順などを変更することができます。また、33行目の出力内容を変更することにより、メールアドレスや名前だけでなく、所属組織情報なども表示可能です。詳しくは公式ドキュメントをご覧ください。

const {google} = require('googleapis');
const key = require('./gsuite_admin_service_account.json');
const scopes = ['https://www.googleapis.com/auth/admin.directory.user'];
const subadress = '[組織に所属する誰かのメールアドレス]';

// サービスアカウント情報(`gsuite_admin_service_account.json`)の読み込み
const jwtClient = new google.auth.JWT(
  key.client_email,
  null,
  key.private_key,
  scopes,
  subadress,
);

// サービスアカウント情報を利用したクライアント認証
jwtClient.authorize();

// APIをコールしアカウント情報を取得し出力
const service = google.admin({version: 'directory_v1'});
service.users.list(
    {
      auth: jwtClient,
      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.');
      }
    }
  );

## 4. まとめ

サービスアカウントを利用することでG Suite管理者による認証のフローを自動化することができました。今回はアカウント情報をリスト表示させてみましたが、Admin SDKのDirectory APIを使用することでアカウントの作成・削除も可能です。また、Directory APIはアカウント情報のみでなく組織・グループ情報を管理することもできます。

G Suiteのアカウントを管理する際には本記事をご参考いただければ幸いと思います。