자습서: 외부 테넌트에서 인증을 위한 React SPA 만들기
이 자습서는 React 단일 페이지 애플리케이션(SPA(권한 있는 액세스 보호))을 빌드하고 Microsoft Entra 관리 센터를 사용하여 인증을 준비하는 방법을 보여 주는 시리즈의 2부입니다. 이 시리즈의 1부에서는 애플리케이션을 등록하고 외부 테넌트에서 사용자 흐름을 구성했습니다. 이 자습서에서는 npm
을 사용하여 React SPA를 만들고 인증 및 권한 부여에 필요한 파일을 만드는 방법을 보여 줍니다.
이 자습서에서는 다음을 수행합니다.
- Visual Studio Code에서 React 프로젝트 만들기
- ID 및 부트스트랩 패키지 설치
- 애플리케이션에 대한 설정 구성
필수 조건
- 자습서: React SPA에서 사용자를 인증하기 위해 외부 테넌트 준비
- React 애플리케이션을 지원하는 모든 IDE(통합 개발 환경)를 사용할 수 있지만 이 자습서에서는 Visual Studio Code를 사용합니다.
- Node.js
React 프로젝트를 만듭니다.
Visual Studio Code를 열고 파일>폴더 열기...를 선택합니다. 프로젝트를 만들 위치로 이동하여 선택합니다.
터미널 >새 터미널을 선택하여 새 터미널을 엽니다.
다음 명령을 실행하여 reactspalocal이라는 이름의 새 React 프로젝트를 만들고, 새 디렉터리로 변경하고, React 프로젝트를 시작합니다. 기본적으로 웹 브라우저는 주소
http://localhost:3000/
으로 열립니다. 브라우저는 열린 상태로 유지되며 변경 내용이 저장될 때마다 다시 렌더링됩니다.npx create-react-app reactspalocal cd reactspalocal npm start
다음과 같은 폴더 구조를 얻으려면 추가 폴더와 파일을 만듭니다.
reactspalocal ├─── public │ └─── index.html └───src ├─── components │ └─── DataDisplay.jsx │ └─── NavigationBar.jsx │ └─── PageLayout.jsx └───styles │ └─── App.css │ └─── index.css └─── utils │ └─── claimUtils.js └── App.jsx └── authConfig.js └── index.js
앱 종속성 업그레이드
사용자 인증을 사용하도록 설정하려면 프로젝트에 ID 관련 npm 패키지를 설치해야 합니다. 프로젝트 스타일 지정에는 부트스트랩이 사용됩니다.
터미널 표시줄에서 + 아이콘을 선택하여 새 터미널을 만듭니다. 다른 터미널이 백그라운드에서 계속 실행될 수 있도록 새 터미널 창이 열립니다.
필요한 경우 reactspalocal로 이동하여 터미널에 다음 명령을 입력하여
msal
및bootstrap
패키지를 설치합니다.npm install @azure/msal-browser @azure/msal-react npm install react-bootstrap bootstrap
인증 구성 파일 authConfig.js를 만듭니다.
src 폴더에서 authConfig.js를 열고 다음 코드 조각을 추가합니다.
/* * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ 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://Enter_the_Tenant_Subdomain_Here.ciamlogin.com/', // Replace the placeholder with your tenant subdomain redirectUri: '/', // Points to window.location.origin. You must register this URI on Azure Portal/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/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" // };
다음 값을 Azure Portal의 값으로 바꿉니다.
Enter_the_Application_Id_Here
값을 찾아 Microsoft Entra 관리 센터에 등록한 앱의 애플리케이션 ID(clientId)로 바꿉니다.- 권한에서
Enter_the_Tenant_Subdomain_Here
를 찾아 테넌트의 하위 도메인으로 바꿉니다. 예를 들어, 테넌트 기본 도메인이contoso.onmicrosoft.com
인 경우contoso
를 사용합니다. 테넌트 이름이 없는 경우 테넌트 세부 정보를 읽는 방법을 알아봅니다.
파일을 저장합니다.
사용자 지정 URL 도메인 사용(선택 사항)
사용자 지정 도메인을 사용하여 인증 URL을 완전히 브랜딩합니다. 사용자 관점에서 볼 때, 사용자는 인증 과정 동안 ciamlogin.com 도메인 이름으로 리디렉션되는 것이 아니라 도메인에 남아 있습니다.
사용자 지정 도메인을 사용하려면 다음 단계를 따릅니다.
외부 테넌트에 대한 사용자 지정 URL 도메인을 사용하도록 설정하려면 외부 테넌트의 앱에 대한 사용자 지정 URL 도메인 사용의 단계를 사용합니다.
authConfig.js 파일에서
auth
개체를 찾은 후 다음을 수행합니다.authority
속성의 값을 https://Enter_the_Custom_Domain_Here/Enter_the_Tenant_ID_Here로 업데이트합니다.Enter_the_Custom_Domain_Here
를 사용자 지정 URL 도메인으로,Enter_the_Tenant_ID_Here
를 테넌트 ID로 바꿉니다. 테넌트 ID가 없는 경우 테넌트 세부 정보를 읽는 방법을 알아봅니다.- [Enter_the_Custom_Domain_Here] 값을 갖는
knownAuthorities
속성을 추가합니다.
authConfig.js 파일을 변경한 후 사용자 지정 URL 도메인이 login.contoso.com이고 테넌트 ID가 aaaabbbb-0000-cccc-1111-dddd2222eeee인 경우 파일은 다음 코드 조각과 유사해야 합니다.
//...
const msalConfig = {
auth: {
authority: process.env.AUTHORITY || 'https://login.contoso.com/aaaabbbb-0000-cccc-1111-dddd2222eeee',
knownAuthorities: ["login.contoso.com"],
//Other properties
},
//...
};
인증 공급자를 포함하도록 index.js 수정
인증이 필요한 앱의 모든 부분을 MsalProvider
구성 요소에 래핑해야 합니다. PublicClientApplication을 인스턴스화한 다음, MsalProvider
에 전달합니다.
src 폴더에서 index.js를 열고 파일 콘텐츠를 다음 코드 조각으로 바꿔
msal
패키지와 부트스트랩 스타일을 사용합니다.import React from 'react'; import ReactDOM 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 = ReactDOM.createRoot(document.getElementById('root')); root.render( <App instance={msalInstance}/> );