MSAL React のイベント コールバック

ほとんどの場合、 @azure/msal-react はログイン呼び出しと応答の処理を抽象化します。 アプリケーション開発者は、保護する必要があるコンポーネントと、ユーザーのサインインに使用する方法を決定する必要がありますが、応答の詳細にあまり関心がない可能性があります。 ただし、アプリケーションがログイン呼び出しの応答に直接アクセスする必要がある場合や、特定のエラーを処理する必要がある場合があります。 @azure/msal-browser は、この目的で使用できる イベント API を公開します。 この記事では、React アプリでこれを利用する方法について説明します。

イベント コールバックの登録と登録解除

イベント API を使用すると、イベントが生成されたときに何かを行うイベント コールバックを登録できます。 React コンポーネントにイベント コールバックを登録する場合は、必ず 2 つのことを行う必要があります。

  1. コールバックは 1 回だけ登録されます。
  2. コールバックは、コンポーネントがマウント解除される前に登録解除されます。

関数コンポーネント

関数コンポーネントでは、空の依存関係配列を持つ useEffect フックを使用してこれを実現できます。 例を次のスニペットに示します。

import { useEffect } from "react";
import { useMsal } from "@azure/msal-react";
import { EventType } from "@azure/msal-browser";

function EventExample() {
    const { instance } = useMsal();

    useEffect(() => {
        // This will be run on component mount
        const callbackId = instance.addEventCallback((message) => {
            // This will be run every time an event is emitted after registering this callback
            if (message.eventType === EventType.LOGIN_SUCCESS) {
                const result = message.payload;    
                // Do something with the result
            }
        });

        return () => {
            // This will be run on component unmount
            if (callbackId) {
                instance.removeEventCallback(callbackId);
            }
        }
        
    }, []);
}

クラス コンポーネント

クラス コンポーネントでは、 componentDidMount と componentWillUnmount を使用してこれを実現できます。

class EventExample extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            callbackId: null;
        }
    }

    componentDidMount() {
        // This will be run on component mount
        const callbackId = this.props.msalContext.instance.addEventCallback((message) => {
            // This will be run every time an event is emitted after registering this callback
            if (message.eventType === EventType.LOGIN_SUCCESS) {
                const result = message.payload;    
                // Do something with the result
            }
        });

        this.setState({callbackId: callbackId});
    }

    componentWillUnmount() {
        // This will be run on component unmount
        if (this.state.callbackId) {
            this.props.msalContext.instance.removeEventCallback(this.state.callbackId);
        }
    }
}

タブとウィンドウ間でログに記録された状態を同期する

ユーザーが別のタブまたはウィンドウでアプリにログインまたはログアウトするときに UI を更新する場合は、 ACCOUNT_ADDED と ACCOUNT_REMOVED イベントをサブスクライブできます。 ペイロードは、追加または削除された AccountInfo オブジェクトになります。

これらのイベントは、既定では生成されません。 これらのイベントを有効にするには、イベント コールバックを登録する前に、 enableAccountStorageEvents API を呼び出す必要があります。

import { useEffect } from "react";
import { useMsal } from "@azure/msal-react";
import { EventType } from "@azure/msal-browser";

function EventExample() {
    const { instance } = useMsal();

    useEffect(() => {
        // This will be run on component mount
        instance.enableAccountStorageEvents();
        const callbackId = instance.addEventCallback((message) => {
            // This will be run every time an event is emitted after registering this callback
            if (message.eventType === EventType.ACCOUNT_ADDED) {
                const account = message.payload;    
                // Update UI
            } else if (message.eventType === EventType.ACCOUNT_REMOVED) {
                const account = message.payload;
                // Update UI
            }
        });

        return () => {
            // This will be run on component unmount
            instance.disableAccountStorageEvents();
            if (callbackId) {
                instance.removeEventCallback(callbackId);
            }
        }
        
    }, []);
}

こちらも参照ください