M365関連 技術

JavaScriptでMicrosoftGraphAPIを使う(Express&MSAL版)

GraphAPIをJavaScriptから呼び出そうとした際に色々と手間取ったので、そのメモです
今回はNodeJSのExpressと@azure/msal-nodeを使用します
以下のMSのドキュメントサイトを参考に実装しています

MSサイト
チュートリアル: Node.js コンソール デーモン アプリで Microsoft Graph を呼び出す - Microsoft identity platform | Microsoft Learn
チュートリアル: Node.js コンソール デーモン アプリで Microsoft Graph を呼び出す - Microsoft identity platform | Microsoft Learn

このチュートリアルでは、Microsoft Graph を呼び出すためのコンソール デーモン アプリを作成します。

続きを読む

アプリを作成する

Azure上で今回使用するアプリを作成します。「Azure Active Directory」>「アプリの登録」>「新規作成」の順にクリックし、アプリケーション名を任意の値、アカウントの種類はシングル、リダイレクトURIを空欄で作成します

登録したアプリの設定

使用するAPIアクセス許可を付与する

必要な権限を付与する

今回は全ユーザーの取得と対象ユーザーの予定取得をするために、【User.Read.All】と【Calendars.Read】のどちらの権限もアプリケーション権限として付与します

作成したアプリの APIのアクセス許可 > アクセス許可の追加 > Microsoft Graph > アプリケーションの許可 > User.Read.All を検索窓に入力し、検索結果のUser配下の方にチェックを付ける > アクセス許可の追加 の順にクリックしていく

【Calendars.Read】も上記画像の【User.Read.All】と同様に権限を付与します

管理者の同意を付与する

今回はアプリケーション権限を付与するため、管理者の同意が必要となるためそれを付与します

赤枠で囲っている~~に管理者の同意を与えますをクリック
赤枠で囲った箇所のように~~に付与されましたとなればOK

シークレットキーを設定

API呼び出し時の認証で使用するシークレットキーを生成します

作成したアプリの 証明書とシークレット > クライアントシークレットタブ > 新しいクライアント シークレット > 説明欄に任意の名前を入れる > 追加 の順にクリックしていく
クライアントシークレットを作成すると画像のようにクリップボードにコピーができるボタンがあるのでそれをクリックして、どこかに保存しておく。時間がたつとボタンが消えてクライアントシークレットの値がわからなくなるので注意が必要

NodeJSのプロジェクトの設定

プロジェクトに必要なものをインストールする

任意のプロジェクトファイル配下で以下のコマンドを実行し、プロジェクトを作成します
今回はRestAPI作成で使用する【Express】とHTTP クライアントである【axios】、GraphAPIのトークン取得時に使用する【@azure/msal-node】(MSALライブラリ)をインストールします。今回は必要最低限のものしかインストールしていないので、必要に応じて適宜追加でインストールしてください

npm init
npm install --save express axios @azure/msal-node

認証に必要なデータを設定

auth.jsというファイルを作成し、そこに認証に必要なデータを記載していきます
各項目については以下のMSサイトを参考にしてください

MSサイト
チュートリアル: Node.js コンソール デーモン アプリで Microsoft Graph を呼び出す - Microsoft identity platform | Microsoft Learn
チュートリアル: Node.js コンソール デーモン アプリで Microsoft Graph を呼び出す - Microsoft identity platform | Microsoft Learn

このチュートリアルでは、Microsoft Graph を呼び出すためのコンソール デーモン アプリを作成します。

続きを読む

const msal = require('@azure/msal-node');

const TENANT_ID = "Azureのアプリ上から取得できるテナントID";
const CLIENT_ID = "Azureのアプリ上から取得できるクライアントID";
const CLIENT_SECRET = "本記事内で取得したクライアントシークレットキーの値";

// 実行環境によっては変更が必要なため以下のMSのサイト記事を参照のこと
const AAD_ENDPOINT = "https://login.microsoftonline.com";
const GRAPH_ENDPOINT = "https://graph.microsoft.com";

const msalConfig = {
    auth: {
        clientId: CLIENT_ID,
        authority: AAD_ENDPOINT + '/' + TENANT_ID,
        clientSecret: CLIENT_SECRET,
    }
};

const tokenRequest = {
    scopes: [GRAPH_ENDPOINT + '/.default'],
};

const apiConfig = {
    uri: GRAPH_ENDPOINT,
};

const cca = new msal.ConfidentialClientApplication(msalConfig);

async function getToken(tokenRequest) {
    return await cca.acquireTokenByClientCredential(tokenRequest);
}

module.exports = {
    apiConfig: apiConfig,
    tokenRequest: tokenRequest,
    getToken: getToken
};

GraphAPIを呼び出す

次に実際にGraphAPIを呼び出し用の関数を作成します

async function callGraphAPI(endpoint) {
    console.log(`endPointURL:${endpoint}`);
    const authResponse = await auth.getToken(auth.tokenRequest);

    const options = {
        headers: {
            Authorization: `Bearer ${authResponse.accessToken}`
        }
    };

    try {
        const response = await axios.get(endpoint, options);
        console.log(response.data);
        return response.data;
    } catch (error) {
        console.log(error)
        return error;
    }
}

では実際にユーザー情報を取得するAPIを作成してみます
今回はPostmanを使用して検証しています

app.get("/getAllUser", (req, res) => {
    var apiURL = "/v1.0/users";
    var select = "";
    if(req.query.select != null)  {
        select = `$select=${req.query.select}`
    }

    if(select != "") {
        apiURL = `${apiURL}?${select}`;
    }

    callGraphAPI(`${auth.apiConfig.uri}${apiURL}`).then(result => {
        res.json({ responseData: result });
    });
});
ユーザー情報の取得に成功しました

対象ユーザーのイベント一覧を取得します

app.get("/getCalendarView", (req, res) => {
    var targetId = req.query.targetId;
    var startDay = req.query.startDay;
    var endDay = req.query.endDay;
    var select = "";
    if(req.query.select != null)  {
        select = `$select=${req.query.select}`
    }

    // 必須となるデータが未定義の場合
    if(targetId == null || startDay == null || endDay == null) {
        res.status(400).send("パラメータが不正です");
        return;
    }

    var apiURL = `/v1.0/users/${targetId}/calendarView?startDateTime=${startDay}T00:00:00&endDateTime=${endDay}T23:59:59`;

    if(select != "") {
        apiURL = `${apiURL}&${select}`;
    }

    callGraphAPI(`${auth.apiConfig.uri}${apiURL}`).then(result => {
        res.json({ responseData: result });
    });
});
こちらも問題なく情報の取得ができました

最後に

今回使用したNodeJSのプロジェクトファイルやJSファイルを以下のGitHubにアップしているので、参考にしてください

サンプル
BlogSampleCodeProjects/MicrosoftGraphAPI_NodeJS_Express_MSAL at main · nasuton/BlogSampleCodeProjects · GitHub
BlogSampleCodeProjects/MicrosoftGraphAPI_NodeJS_Express_MSAL at main · nasuton/BlogSampleCodeProjects · GitHub

Project for sample code used in the blog.(Blogで記載しているサンプルコード ...

続きを読む

会社紹介

私が所属しているアドバンスド・ソリューション株式会社(以下、ADS)は一緒に働く仲間を募集しています

会社概要
「技術」×「知恵」=顧客課題の解決・新しい価値の創造

この方程式の実現はADSが大切にしている考えで、技術を磨き続けるgeekさと、顧客を思うloveがあってこそ実現できる世界観だと思っています
この『love & geek』の精神さえあれば、得意不得意はno problem!
技術はピカイチだけど顧客折衝はちょっと苦手。OKです。技術はまだ未熟だけど顧客と知恵を出し合って要件定義するのは大好き。OKです
凸凹な社員の集まり、色んなカラーや柄の個性が集まっているからこそ、常に新しいソリューションが生まれています

ミッション
私たちは、テクノロジーを活用し、業務や事業の生産性向上と企業進化を支援します

ホームページ
アドバンスド・ソリューション株式会社
アドバンスド・ソリューション株式会社

アドバンスド・ソリューションは主にMicrosoft製品を使用して、企業の生産性向上に取り組んでいます。要件定義から導入 ...

サイトへ移動

お問い合わせ
お問い合わせ  | アドバンスド・ソリューション株式会社
お問い合わせ | アドバンスド・ソリューション株式会社

お問い合わせはこちら

-M365関連, 技術
-, ,