はじめに
ReactでAzure ADを使用したログイン認証や、Graph APIとの連携を実現したいことがあると思います。
自前で実装するのか・・・と落胆する必要はなく、Microsoftがmsal-reactといったライブラリを提供しています!msal-reactを使用することでAzure AD認証を簡単に自前のアプリに組み込むことができ、Graph APIとの連携も容易となるので紹介させてください!
事前準備
Reactアプリ作成
今回もviteを使ってReactアプリを作成します。
npm create vite@latest
作成後はAzure AD認証を実現する@azure/msal-browser,@azure/msal-react
とHTTPライブラリaxios
を入れておきます。
npm install @azure/msal-browser @azure/msal-react axios
インストールしたら動作確認しておきましょう。
npm run dev
動作確認
Azure AD ギャラリーに独自のアプリケーションを追加
Azure AD ギャラリーに独自のアプリケーションを追加します。
独自アプリケーションを事前に登録することで、Azure AD認証を組み込むことを可能とします。
下記画面から独自のアプリケーションの作成
を選択します。
名前は任意のものを入れていただいて構いません。今回はReactAuthTest
としています。
開発中アプリのため、アプリケーションを登録してAzure ADと統合します
を選択します。
Azure ADに登録されているユーザーのみ認証したいためこの組織ディレクトリのみに含まれるアカウント
を選択します。
リダイレクトURIはviteでデバッグするときのURI:http://localhost:5173/
を指定し、アプリケーションの種別はシングルページアプリケーション
を指定します。
赤枠部分の説明にも記載があるようにアプリケーションはシングルページアーキテクチャであり、承認コードフローを使用しないので、アクセストークン
、IDトークン
のチェックボックスを有効にします。
これで準備は完了です!
下記2点はReactアプリケーションで使用する情報なのでメモしておきましょう。
- アプリケーション(クライアント)ID
Azure AD ギャラリーに追加したアプリの概要ブレードを開き、赤枠部分のアプリケーション(クライアント)IDの値
- プライマリ ドメイン
Azure Active Directoryの概要ブレードを開き、赤枠部分のプライマリ ドメインの値
実装(Azure AD認証)
先ほどメモした情報を.env
に環境変数として記載します。
viteでReactプロジェクトを作成した場合は、キー名のプレフィックスにVITE
とつけることで環境変数として使用可能です。
-
VITE_CLIENT_ID
はメモしたアプリケーション(クライアント)IDの値 -
VITE_AUTHORITY
はメモしたプライマリ ドメインの値 -
VITE_REDIRECT_URI
はリダイレクトURIで指定したURI
VITE_CLIENT_ID = "メモしたアプリケーション(クライアント)IDの値"
VITE_AUTHORITY = "メモしたプライマリ ドメインの値"
VITE_REDIRECT_URI = "http://localhost:5173/"
まずはmain.jsx
に処理を追記します。
認証を行うインスタンスを作成し、MsalProvider
を使用してそれぞれのコンポーネントが認証を実行できるようにします。
接続情報は.env
から取得し、認証に成功した場合のアクセストークン保存先はsessionStorage
を指定します。
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
+ //インポートを追加
+ import { PublicClientApplication } from "@azure/msal-browser";
+ import { MsalProvider } from "@azure/msal-react";
+ //msalInstanceを作成
+ const msalInstance = new PublicClientApplication({
+ auth: {
+ //環境変数から認証情報を取得
+ //アプリケーション(クライアント)ID
+ clientId: import.meta.env.VITE_CLIENT_ID,
+ //プライマリ ドメイン
+ authority: `https://login.microsoftonline.com/${
+ import.meta.env.VITE_AUTHORITY
+ }`,
+ //リダイレクトURI
+ redirectUri: import.meta.env.VITE_REDIRECT_URI,
+ },
+ //キャッシュ先
+ cache: {
+ //セッションストレージ
+ cacheLocation: "sessionStorage",
+ },
+ });
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
+ <MsalProvider instance={msalInstance}>
<App />
+ </MsalProvider>
</React.StrictMode>
);
次にApp.jsx
に機能を追加します。先にライブラリから必要なコンポーネントやHooksをインポートしておきます。
+ import React, { useState } from "react";
+ import {
+ AuthenticatedTemplate,
+ UnauthenticatedTemplate,
+ useMsal,
+ } from "@azure/msal-react";
Azure AD認証を実行するログインボタンを作成していきます。
引数でGraph APIで要求する権限を指定する必要があるため、今回はユーザー情報を取得する権限User.Read
を要求します。
要件に応じて使用したい権限は変わってくると思うので、詳しくは公式ドキュメントを参考にしていただければと思います。
ログインボタンを押下したらProviderから受け取ったインスタンスに提供されているメソッドloginRedirect
を実行して、Azure AD認証の画面へリダイレクトさせます。
+ //Azure AD認証でGraph APIに要求する権限
+ const loginRequest = {
+ //ユーザーを取得する権限
+ scopes: ["User.Read"]
+ };
+ /**
+ * ログインボタンを押下したらAzure ADの認証画面へリダイレクトさせる
+ * @returns ログインボタンコンポーネント
+ */
+ const LoginButton = () => {
+ //ProviderからAD認証用のインスタンスを取得
+ const { instance } = useMsal();
+ //ログインボタン実行時の関数
+ const handleLogin = () => {
+ //AD認証実現画面へリダイレクト。引数にGraph APIに要求する権限を設定
+ instance.loginRedirect(loginRequest);
+ };
+ return (
+ <>
+ <button onClick={() => handleLogin()}>ログイン</button>
+ </>
+ );
+ };
export default function App() {
return (
<div className="App">
+ {/*ログイン成功時に表示*/}
+ <AuthenticatedTemplate>
+ <div>ログインに成功しました!</div>
+ </AuthenticatedTemplate>
+ {/*未ログイン時に表示*/}
+ <UnauthenticatedTemplate>
+ <div>ログインしてください</div>
+ <LoginButton />
+ </UnauthenticatedTemplate>
</div>
);
}
AuthenticatedTemplate
タグ内のコンポーネントはログイン後に表示されて、UnauthenticatedTemplate
タグ内のコンポーネントは未ログイン状態の時に表示されます。
未ログイン状態ではログインボタンを表示したいのでUnauthenticatedTemplate
タグ内に配置します。
Azure AD認証の実装は完了したので動作確認します!
動作確認
初期表示
ログインボタン押下後
Microsoftが提供するAzure AD認証のログイン画面が表示されました!
ログイン完了後
ログイン後はリダイレクトURIに指定したhttp://localhost:5173/
にリダイレクトされていますね。またログインに成功したため、AuthenticatedTemplate
内の文言が表示されています!
Session Storage
Session Storage
を確認すると、取得したIdToken
など保存されていますね!
次はログインした状態でGraph APIと連携できるよう実装を進めていきます。
実装(Graph APIと連携)
アクセストークンを引数で受け取り、Graph APIを使用してユーザー情報を取得する関数を作成します。
+ /**
+ * Graph APIをコールしユーザー情報を取得する
+ * @param {Object} accessToken
+ * @returns Graph APIで取得したユーザー情報
+ */
+ const callGraphApi = async (accessToken) => {
+ //受け取ったアクセストークンをヘッダーに設定してGraph APIをコール
+ const response = await axios.get("https://graph.microsoft.com/v1.0/me", {
+ headers: {
+ Authorization: `Bearer ${accessToken}`,
+ },
+ });
+ return response.data;
+ };
今回はユーザー情報を取得するエンドポイントGET /me
を使用していますが、メールを作成したいなど要件に応じて使用するエンドポイントは変わってきますので、こちらも公式ドキュメントを参照していただければと思います。
アクセストークンを取得してGraph APIを実行し、取得したユーザー情報を表示するコンポーネントを作成します。
//Azure AD認証でGraph APIに要求する権限
const loginRequest = {
//ユーザーを取得する権限
scopes: ["User.Read"]
};
+ /**
+ * Graph APIをコールし、取得したユーザー情報を表示するコンポーネント
+ * @returns ユーザー情報表示コンポーネント
+ */
+ const ProfileContent = () => {
+ //accountsはログイン時に取得したユーザー情報
+ const { instance, accounts } = useMsal();
+ //Graph APIで取得するデータのState
+ const [graphData, setGraphData] = useState(null);
+
+ function RequestProfileData() {
+ //★accuireTokenSilentを使用してアクセストークンを取得する。
+ instance
+ .acquireTokenSilent({
+ ...loginRequest, //Graph APIに要求する権限
+ account: accounts[0],//ログインユーザー情報
+ })
+ //取得に成功したらアクセストークンをGraph API実行関数に渡して実行
+ .then((response) => {
+ callGraphApi(response.accessToken).then((data) => {
+ //Graph APIのデータをStateに保存
+ setGraphData(data);
+ console.log(data);
+ });
+ });
+ }
+ return (
+ <>
+ <h5 className="">Welcome {accounts[0].name}</h5>
+ <br />
+ {/*Graph APIのデータがStateに保存されている場合*/}
+ {graphData ? (
+ <div>
+ <div>id:{graphData.id}</div>
+ <div>名前:{graphData.displayName}</div>
+ </div>
+ ) : (
+ {/*Graph APIのデータがStateに保存されていない場合*/}
+ <button variant="secondary" onClick={RequestProfileData}>
+ Graph API実行
+ </button>
+ )}
+ </>
+ );
+ };
★マークの処理について説明すると下記流れになります。
-
acquireTokenSilent
メソッドでAzure AD認証で取得したユーザー情報とGraph APIに要求する権限を引数に設定してアクセストークンを取得する。 - アクセストークンを
callGraphApi
の引数に設定して、ユーザー情報を取得する。 - ユーザー情報をStateに保持し、画面に表示する。
最後に作成したコンポーネントをログイン時に表示するようにします。
export default function App() {
return (
<div className="App">
{/*ログイン成功時に表示*/}
<AuthenticatedTemplate>
- <div>ログインに成功しました!</div>
+ <ProfileContent />
</AuthenticatedTemplate>
{/*未ログイン時に表示*/}
<UnauthenticatedTemplate>
<div>ログインしてください</div>
<LoginButton />
</UnauthenticatedTemplate>
</div>
);
}
実装完了です!動作確認していきます。
動作確認
ログイン後画面
ログイン後に表示される画面です。ここでGraph API実行
ボタンを押下します。
Graph API実行ボタンを押下後
Graph APIで取得した情報が無事表示されましたね!
おわりに
msal-reactはいかがでしたでしょうか?Azure AD認証が簡単に実現できたと思います!
また、ログイン後のアクセストークン取得やGraph APIとの連携も簡単です。
ReactでAzure AD認証を使用する場合はぜひ使ってみてください!