教程:创建 React 单页应用程序并将其准备用于身份验证

适用于:带白色勾号的绿色圆圈。 员工租户 带白色勾号的绿色圆圈。 外部租户(了解详细信息

在本教程中,你将生成 React 单页应用程序(SPA),并准备使用Microsoft标识平台进行身份验证。 本教程演示如何使用 npmReact SPA 创建、创建身份验证和授权所需的文件,并将租户详细信息添加到源代码。 应用程序可用于员工租户中的员工或使用外部租户的客户。

在本教程中,你将:

  • 创建新的 React 项目
  • 安装身份验证所需的包
  • 创建文件结构并将代码添加到服务器文件
  • 将租户详细信息添加到身份验证配置文件

先决条件

创建新的 React 项目

  1. 打开 Visual Studio Code,选择“文件>“打开文件夹...”。导航到要在其中创建项目的位置并选中该位置。

  2. 通过选择“终端”>“新终端”打开一个新的终端。

  3. 运行以下命令以创建一个名为 reactspalocal 的新 React 项目,然后更改为新的目录并启动该 React 项目。 默认情况下,Web 浏览器将使用地址 http://localhost:3000/ 打开。 浏览器保持打开状态,并重新呈现保存的每个更改。

    npx create-react-app reactspalocal
    cd reactspalocal
    npm start
    
  4. 创建其他文件夹和文件,实现以下文件夹结构:

    ├─── public
    │   └─── index.html
    └───src
        └─── styles
        │   └─── App.css
        │   └─── index.css
        ├─── utils
        │   └─── claimUtils.js
        ├─── components
        │   └─── DataDisplay.jsx
        │   └─── NavigationBar.jsx
        │   └─── PageLayout.jsx
        └── App.jsx
        └── authConfig.js
        └── index.js
    

安装标识和启动包

必须在项目中安装与身份验证相关的 npm 包才能启用用户身份验证。 对于项目样式设置,将使用 Bootstrap

  1. 在“终端”栏中,选择 + 图标以创建新终端。 此时会打开单独的终端窗口,上一个节点终端将继续在后台运行。

  2. 确保选择正确的目录(reactspalocal),然后在终端中输入以下内容以安装相关 msalbootstrap 包。

    npm install @azure/msal-browser @azure/msal-react
    npm install react-bootstrap bootstrap
    

将租户详细信息添加到 MSAL 配置

authConfig.js 文件包含身份验证流的配置设置,用于使用所需的身份验证设置来配置 MSAL.js

  1. 在 src 文件夹中,打开 authConfig.js 并添加以下代码片段:

    
     import { LogLevel } from '@azure/msal-browser';
    
     /**
     * Configuration object to be passed to MSAL instance on creation. 
     * For a full list of MSAL.js configuration parameters, visit:
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md 
     */
    
     export const msalConfig = {
         auth: {
             clientId: 'Enter_the_Application_Id_Here', // This is the ONLY mandatory field that you need to supply.
             authority: 'https://login.microsoftonline.com/Enter_the_Tenant_Info_Here', // Replace the placeholder with your tenant info
             redirectUri: 'http://localhost:3000/redirect', // Points to window.___location.origin. You must register this URI on Microsoft Entra admin center/App Registration.
             postLogoutRedirectUri: '/', // Indicates the page to navigate after logout.
             navigateToLoginRequestUrl: false, // If "true", will navigate back to the original request ___location before processing the auth code response.
         },
         cache: {
             cacheLocation: 'sessionStorage', // Configures cache ___location. "sessionStorage" is more secure, but "localStorage" gives you SSO between tabs.
             storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge
         },
         system: {
             loggerOptions: {
                 loggerCallback: (level, message, containsPii) => {
                     if (containsPii) {
                         return;
                     }
                     switch (level) {
                         case LogLevel.Error:
                             console.error(message);
                             return;
                         case LogLevel.Info:
                             console.info(message);
                             return;
                         case LogLevel.Verbose:
                             console.debug(message);
                             return;
                         case LogLevel.Warning:
                             console.warn(message);
                             return;
                         default:
                             return;
                     }
                 },
             },
         },
     };
    
     /**
     * Scopes you add here will be prompted for user consent during sign-in.
     * By default, MSAL.js will add OIDC scopes (openid, profile, email) to any login request.
     * For more information about OIDC scopes, visit: 
     * https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
     */
     export const loginRequest = {
         scopes: [],
     };
    
     /**
     * An optional silentRequest object can be used to achieve silent SSO
     * between applications by providing a "login_hint" property.
     */
     // export const silentRequest = {
     //     scopes: ["openid", "profile"],
     //     loginHint: "example@___domain.net"
     // };
    
  2. 将下列值替换为 Microsoft Entra 管理中心中的值。

    • clientId - 应用程序的标识符,也称为客户端。 将 Enter_the_Application_Id_Here 替换为注册应用程序的概述页中先前记录的应用程序(客户端) ID 值。
    • authority - 它是由两个部分组成:
      • 实例是云提供商的终结点。 在“国家云”查看可用的不同终结点。
      • “租户 ID”是在其中注册应用程序的租户的标识符。 将 Enter_the_Tenant_Info_Here 替换为已注册应用程序的概述页中先前记录的“目录(租户)ID”值。
  3. 保存文件。

添加身份验证提供商

msal 用于在应用程序中提供身份验证。 包 msal-browser 用于处理身份验证流,包 msal-react 用于与 React 集成 msal-browseraddEventCallback 用于侦听身份验证过程中发生的事件,例如当用户成功登录时。 setActiveAccount 方法用于设置应用程序的活动帐户,它将用于确定要显示的用户信息。

  1. src 文件夹中,打开 index.js,将该文件的内容替换为以下代码片段以使用 msal 包和 Bootstrap 样式:

    import React from 'react';
    import { createRoot } from 'react-dom/client';
    import App from './App';
    import { PublicClientApplication, EventType } from '@azure/msal-browser';
    import { msalConfig } from './authConfig';
    
    import 'bootstrap/dist/css/bootstrap.min.css';
    import './styles/index.css';
    
    /**
    * MSAL should be instantiated outside of the component tree to prevent it from being re-instantiated on re-renders.
    * For more, visit: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-react/docs/getting-started.md
    */
    const msalInstance = new PublicClientApplication(msalConfig);
    
    // Default to using the first account if no account is active on page load
    if (!msalInstance.getActiveAccount() && msalInstance.getAllAccounts().length > 0) {
        // Account selection logic is app dependent. Adjust as needed for different use cases.
        msalInstance.setActiveAccount(msalInstance.getActiveAccount()[0]);
    }
    
    // Listen for sign-in event and set active account
    msalInstance.addEventCallback((event) => {
        if (event.eventType === EventType.LOGIN_SUCCESS && event.payload.account) {
            const account = event.payload.account;
            msalInstance.setActiveAccount(account);
        }
    });
    
    const root = createRoot(document.getElementById('root'));
    root.render(
        <App instance={msalInstance}/>
    );
    
  2. 保存文件。

若要了解有关这些包的详细信息,请参阅以下文档:msal-browsermsal-react

添加主应用程序组件

需要身份验证的所有应用部分均必须包装在 MsalProvider 组件中。 设置一个 instance 变量,该变量调用 useMsal 挂钩以获取 PublicClientApplication 实例,然后将其传递给 MsalProviderMsalProvider 组件通过 React 的上下文 API 在整个应用中提供 PublicClientApplication 实例。 所有MsalProvider下的组件将通过上下文访问PublicClientApplication实例,并且所有由msal-react提供的挂钩和组件也可供使用。

  1. src 文件夹中,打开 App.jsx 并将文件的内容替换为以下代码片段:

    import { MsalProvider, AuthenticatedTemplate, useMsal, UnauthenticatedTemplate } from '@azure/msal-react';
    import { Container, Button } from 'react-bootstrap';
    import { PageLayout } from './components/PageLayout';
    import { IdTokenData } from './components/DataDisplay';
    import { loginRequest } from './authConfig';
    
    import './styles/App.css';
    
    /**
    * Most applications will need to conditionally render certain components based on whether a user is signed in or not. 
    * msal-react provides 2 easy ways to do this. AuthenticatedTemplate and UnauthenticatedTemplate components will 
    * only render their children if a user is authenticated or unauthenticated, respectively. For more, visit:
    * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-react/docs/getting-started.md
    */
    const MainContent = () => {
        /**
        * useMsal is hook that returns the PublicClientApplication instance,
        * that tells you what msal is currently doing. For more, visit:
        * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-react/docs/hooks.md
        */
        const { instance } = useMsal();
        const activeAccount = instance.getActiveAccount();
    
        const handleRedirect = () => {
            instance
                .loginRedirect({
                    ...loginRequest,
                    prompt: 'create',
                })
                .catch((error) => console.log(error));
        };
        return (
            <div className="App">
                <AuthenticatedTemplate>
                    {activeAccount ? (
                        <Container>
                            <IdTokenData idTokenClaims={activeAccount.idTokenClaims} />
                        </Container>
                    ) : null}
                </AuthenticatedTemplate>
                <UnauthenticatedTemplate>
                    <Button className="signInButton" onClick={handleRedirect} variant="primary">
                        Sign up
                    </Button>
                </UnauthenticatedTemplate>
            </div>
        );
    };
    
    
    /**
    * msal-react is built on the React context API and all parts of your app that require authentication must be 
    * wrapped in the MsalProvider component. You will first need to initialize an instance of PublicClientApplication 
    * then pass this to MsalProvider as a prop. All components underneath MsalProvider will have access to the 
    * PublicClientApplication instance via context as well as all hooks and components provided by msal-react. For more, visit:
    * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-react/docs/getting-started.md
    */
    const App = ({ instance }) => {
        return (
            <MsalProvider instance={instance}>
                <PageLayout>
                    <MainContent />
                </PageLayout>
            </MsalProvider>
        );
    };
    
    export default App;
    
  2. 保存文件。

后续步骤