MSAL React では、関数コンポーネントとクラス コンポーネントの両方がサポートされています。 この記事では、クラス コンポーネントで MSAL React を使用する方法について説明します。これにより、クラス コンポーネント内の MSAL React コンテキストを初期化、保護、アクセスできます。
クラス コンポーネント内で @azure/msal-react フックを使用できないことに注意することが重要です。 クラス コンポーネント内の認証状態にアクセスする必要がある場合は、 @azure/msal-browser を直接使用して同様の機能を取得する必要があります。
Prerequisites
初期化
MSAL React を使用したクラス コンポーネントを使用した初期化は、関数コンポーネントとよく似ています。 関数コンポーネントを使用する場合と同様に、認証状態へのアクセスを必要とするコンポーネント ツリーの最上位レベルに MsalProvider コンポーネントが必要です。
次のスニペットでは、 MsalProvider コンポーネントを使用してアプリケーション全体をラップし、すべての子コンポーネントで MSAL インスタンスを使用できるようにします。 これにより、子コンポーネントは、ユーザー認証、トークンの取得、保護された API の呼び出しに MSAL を使用できます。
import React from "react";
import { MsalProvider } from "@azure/msal-react";
import { PublicClientApplication } from "@azure/msal-browser";
const pca = new PublicClientApplication(config);
class App extends React.Component {
render() {
return (
<MsalProvider instance={pca}>
<YourAppComponents>
</ MsalProvider>
);
}
}
コンポーネントの保護
MSAL React では、コンポーネントを保護し、ユーザーの認証状態に基づいて条件付きでレンダリングできます。 これは、関数コンポーネントの使用と同様に機能します。 主な例は次のとおりです。
-
AuthenticatedTemplate- このコンポーネントは、ユーザーが認証された場合にのみ子をレンダリングします。 ユーザーが認証されていない場合、何もレンダリングされません。 -
UnauthenticatedTemplate- このコンポーネントは、ユーザーが認証されていない場合にのみ子をレンダリングします。 ユーザーが認証されている場合、何もレンダリングされません。 -
MsalAuthenticationTemplate- このコンポーネントは、子をレンダリングする前にユーザーの認証を試みます。 相互作用の種類 (リダイレクトまたはポップアップ) を prop として指定できます。ユーザーが認証されていない場合は、認証プロセスが開始されます。
次のスニペットは、 AuthenticatedTemplate、 UnauthenticatedTemplate、 MsalAuthenticationTemplate を使用して React コンポーネントを保護する方法を示しています。
MSAL Provider が子コンポーネントを囲んでいることに注目してください。
import React from "react";
import { MsalProvider, AuthenticatedTemplate, UnauthenticatedTemplate, MsalAuthenticationTemplate } from "@azure/msal-react";
import { PublicClientApplication, InteractionType } from "@azure/msal-browser";
const pca = new PublicClientApplication(config);
class App extends React.Component {
render() {
return (
<MsalProvider instance={pca}>
<AuthenticatedTemplate>
<span>This will only render for authenticated users</span>
</ AuthenticatedTemplate>
<UnauthenticatedTemplate>
<span>This will only render for unauthenticated users</span>
</ UnauthenticatedTemplate>
<MsalAuthenticationTemplate interactionType={InteractionType.Popup}>
<span>This will only render for authenticated users.</span>
</ MsalAuthenticationTemplate>
</ MsalProvider>
);
}
}
クラス コンポーネント内の MSAL React コンテキストへのアクセス
useMsal フックを使用して、クラス コンポーネント内の MSAL React コンテキストにアクセスすることはできません。 これは、フックは、インスタンスなしで機能を使用できる関数コンポーネントでのみ使用できるためです。 クラス コンポーネントにはインスタンスがあるため、他に 2 つのオプションがあります。 生のコンテキストを直接使用するか、 withMsal 上位のコンポーネントを使用してコンポーネントのプロパティにコンテキストを挿入できます。
生コンテキストへのアクセス
次のスニペットは、 MsalContext を使用して、クラス コンポーネント内の生のコンテキストにアクセスする方法を示しています。
import React from "react";
import { MsalProvider, MsalContext } from "@azure/msal-react";
import { PublicClientApplication } from "@azure/msal-browser";
const pca = new PublicClientApplication(config);
class App extends React.Component {
render() {
return (
<MsalProvider instance={pca}>
<YourClassComponent/>
</ MsalProvider>
);
}
}
class YourClassComponent extends React.Component {
static contextType = MsalContext;
render() {
const isAuthenticated = this.context.accounts.length > 0;
if (isAuthenticated) {
return <span>There are currently {this.context.accounts.length} users signed in!</span>
}
}
}
実際の例については、react-router-sample の ProfileRawContext.jsx を参照してください。
withMsal HOC を介したアクセス
別の方法として、 withMsal 上位コンポーネントを使用して、コンポーネントのプロパティにコンテキストを挿入します。 次のスニペットは、 withMsal HOC を使用してクラス コンポーネント内の MSAL React コンテキストにアクセスする方法を示しています。
import React from "react";
import { MsalProvider, withMsal } from "@azure/msal-react";
import { PublicClientApplication } from "@azure/msal-browser";
const pca = new PublicClientApplication(config);
class YourClassComponent extends React.Component {
render() {
const isAuthenticated = this.props.msalContext.accounts.length > 0;
if (isAuthenticated) {
return <span>There are currently {this.props.msalContext.accounts.length} users signed in!</span>
}
}
}
const YourWrappedComponent = withMsal(YourClassComponent);
class App extends React.Component {
render() {
return (
<MsalProvider instance={pca}>
<YourWrappedComponent />
</ MsalProvider>
);
}
}
実際の例については、react-router-sample の ProfileWithMsal.jsx を参照してください。
クラス コンポーネントを使用したログイン
MSAL React コンテキストを取得するために実行する方法に関係なく、使用は同じになります。 コンテキスト オブジェクトを取得したら、でPublicClientApplication呼び出したり、サインインしているアカウントを調べたり、認証が現在進行中かどうかを判断したりできます。
次の例では、 withMsal HOC アプローチを使用してログインする方法を示しますが、必要に応じて他のアプローチにすばやく適応できます。
Note
MsalProvider コンポーネントは、コンテキストを使用するコンポーネントの上の任意のレベルでレンダリングする必要があります。 次の例では、プロバイダーがあることを前提としており、これを示しません。
ボタンをクリックした結果としてログインする
次のスニペットでは、LoginButton上位コンポーネントを使用する React クラス コンポーネント withMsalを定義します。 ユーザーが認証されていない場合はログイン ポップアップをトリガーするか、認証された場合はユーザーをログアウトするボタンがレンダリングされます。
import React from "react";
import { withMsal } from "@azure/msal-react";
class LoginButton extends React.Component {
render() {
const isAuthenticated = this.props.msalContext.accounts.length > 0;
const msalInstance = this.props.msalContext.instance;
if (isAuthenticated) {
return <button onClick={() => msalInstance.logout()}>Logout</button>
} else {
return <button onClick={() => msalInstance.loginPopup()}>Login</button>
}
}
}
export default YourWrappedComponent = withMsal(LoginButton);
ページ読み込み時のログイン
次のスニペットでは、ProtectedComponent上位コンポーネントを使用する React クラス コンポーネント withMsalを定義します。 マウントと更新時にユーザーの認証が試行され、ユーザーが認証されているかどうか、または読み込みページで認証が進行中かどうかを表示します。
import React from "react";
import { withMsal } from "@azure/msal-react";
import { InteractionStatus } from "@azure/msal-browser";
class ProtectedComponent extends React.Component {
callLogin() {
const isAuthenticated = this.props.msalContext.accounts.length > 0;
const msalInstance = this.props.msalContext.instance;
// If a user is not logged in and authentication is not already in progress, invoke login
if (!isAuthenticated && this.props.msalContext.inProgress === InteractionStatus.None) {
msalInstance.loginPopup();
}
}
componentDidMount() {
this.callLogin();
}
componentDidUpdate() {
this.callLogin();
}
render() {
const isAuthenticated = this.props.msalContext.accounts.length > 0;
if (isAuthenticated) {
return <span>User is authenticated</span>
} else {
return <span>Authentication in progress</span>;
}
}
}
export default YourWrappedComponent = withMsal(ProtectedComponent);
こちらも参照ください
- react-router-sample を確認してください。