적용 대상:
외부 테넌트(자세한 정보)
이 자습서에서는 네이티브 인증 JavaScript SDK를 사용하여 사용자를 React SPA(단일 페이지 앱)에 로그인하는 방법을 알아봅니다.
이 자습서에서는 다음을 수행합니다.
- 사용자를 로그인하도록 React 앱을 업데이트합니다.
- 로그인 흐름을 테스트합니다.
필수 조건
UI 구성 요소 만들기
이 섹션에서는 사용자의 로그인 정보를 수집하는 양식을 만듭니다.
src/app/sign-in이라는 폴더를 만듭니다.
로그인/구성 요소/InitialForm.tsx 파일을 만든 다음 로그인/구성 요소/InitialForm.tsx의 코드를 붙여넣습니다. 이 구성 요소는 사용자의 사용자 이름(이메일)을 수집하는 양식을 표시합니다.
선택한 인증 방법이 전자 메일 및 일회성 암호인 경우 로그인/구성 요소/CodeForm.tsx 파일을 만든 다음 로그인 /구성 요소/CodeForm.tsx의 코드를 붙여넣습니다. 관리자가 전자 메일 일회용 암호를 Microsoft Entra 관리 센터의 로그인 흐름으로 설정하는 경우 이 구성 요소는 사용자로부터 일회성 암호를 수집하는 양식을 표시합니다.
선택한 인증 방법이 전자 메일 및 암호인 경우 로그인/구성 요소/PasswordForm.tsx 파일을 만든 다음 로그인/구성 요소/PasswordForm.tsx의 코드를 붙여넣습니다. 이 구성 요소는 사용자의 암호를 수집하는 양식을 표시합니다.
로그인/구성 요소/UserInfo.tsx 파일을 만든 다음 로그인/구성 요소/UserInfo.tsx의 코드를 붙여넣습니다. 이 구성 요소는 로그인한 사용자의 사용자 이름 및 로그인 상태를 표시합니다.
양식 상호 작용 처리
이 섹션에서는 로그인 흐름 시작, 사용자 암호 제출 또는 일회성 암호 제출과 같은 로그인 양식 상호 작용을 처리하는 코드를 추가합니다.
로그인 흐름에 대한 논리를 처리하는 로그인/page.tsx 파일을 만듭니다. 이 파일에서 다음을 확인할 수 있습니다.
필요한 구성 요소를 가져오고 상태에 따라 적절한 양식을 표시합니다. 로그인/page.tsx의 전체 예제를 참조하세요.
import { CustomAuthPublicClientApplication, ICustomAuthPublicClientApplication, SignInCodeRequiredState, // Uncommon if using a Email + Password flow // SignInPasswordRequiredState, SignInCompletedState, AuthFlowStateBase, } from "@azure/msal-browser/custom-auth"; export default function SignIn() { const [authClient, setAuthClient] = useState<ICustomAuthPublicClientApplication | null>(null); const [username, setUsername] = useState(""); //If you are sign in using a Email + Password flow, uncomment the following line //const [password, setPassword] = useState(""); const [code, setCode] = useState(""); const [error, setError] = useState(""); const [loading, setLoading] = useState(false); const [signInState, setSignInState] = useState<AuthFlowStateBase | null>(null); const [data, setData] = useState<CustomAuthAccountData | undefined>(undefined); const [loadingAccountStatus, setLoadingAccountStatus] = useState(true); const [isSignedIn, setCurrentSignInStatus] = useState(false); useEffect(() => { const initializeApp = async () => { const appInstance = await CustomAuthPublicClientApplication.create(customAuthConfig); setAuthClient(appInstance); }; initializeApp(); }, []); useEffect(() => { const checkAccount = async () => { if (!authClient) return; const accountResult = authClient.getCurrentAccount(); if (accountResult.isCompleted()) { setCurrentSignInStatus(true); } setData(accountResult.data); setLoadingAccountStatus(false); }; checkAccount(); }, [authClient]); const renderForm = () => { if (loadingAccountStatus) { return; } if (isSignedIn || signInState instanceof SignInCompletedState) { return <UserInfo userData={data} />; } //If you are signing up using Email + Password flow, uncomment the following block of code /* if (signInState instanceof SignInPasswordRequiredState) { return ( <PasswordForm onSubmit={handlePasswordSubmit} password={password} setPassword={setPassword} loading={loading} /> ); } */ if (signInState instanceof SignInCodeRequiredState) { return <CodeForm onSubmit={handleCodeSubmit} code={code} setCode={setCode} loading={loading} />; } return <InitialForm onSubmit={startSignIn} username={username} setUsername={setUsername} loading={loading} />; }; return ( <div style={styles.container}> <h2 style={styles.h2}>Sign In</h2> <> {renderForm()} {error && <div style={styles.error}>{error}</div>} </> </div> ); }로그인 흐름을 시작하려면 다음 코드 조각을 사용합니다. 코드 조각을 배치할 위치를 알아보려면 로그인/page.tsx 에서 전체 예제를 참조하세요.
const startSignIn = async (e: React.FormEvent) => { e.preventDefault(); setError(""); setLoading(true); if (!authClient) return; // Start the sign-in flow const result = await authClient.signIn({ username, }); // Thge result may have the different states, // such as Password required state, OTP code rquired state, Failed state and Completed state. if (result.isFailed()) { if (result.error?.isUserNotFound()) { setError("User not found"); } else if (result.error?.isInvalidUsername()) { setError("Username is invalid"); } else if (result.error?.isPasswordIncorrect()) { setError("Password is invalid"); } else { setError(`An error occurred: ${result.error?.errorData?.errorDescription}`); } } if (result.isCompleted()) { setData(result.data); } setSignInState(result.state); setLoading(false); };SDK의 인스턴스 메서드는
signIn()로그인 흐름을 시작합니다.선택한 인증 흐름이 전자 메일 및 일회성 암호인 경우 다음 코드 조각을 사용하여 일회성 암호를 제출합니다. 코드 조각을 배치할 위치를 알아보려면 로그인/page.tsx 에서 전체 예제를 참조하세요.
const handleCodeSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(""); setLoading(true); if (signInState instanceof SignInCodeRequiredState) { const result = await signInState.submitCode(code); // the result object may have the different states, such as Failed state and Completed state. if (result.isFailed()) { if (result.error?.isInvalidCode()) { setError("Invalid code"); } else { setError(result.error?.errorData?.errorDescription || "An error occurred while verifying the code"); } } if (result.isCompleted()) { setData(result.data); setSignInState(result.state); } } setLoading(false); };로그인 상태의
submitCode()일회성 암호를 제출합니다.선택한 인증 흐름이 전자 메일 및 암호인 경우 다음 코드 조각을 사용하여 사용자의 암호를 제출합니다. 코드 조각을 배치할 위치를 알아보려면 로그인/page.tsx 에서 전체 예제를 참조하세요.
const handlePasswordSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(""); setLoading(true); if (signInState instanceof SignInPasswordRequiredState) { const result = await signInState.submitPassword(password); if (result.isFailed()) { if (result.error?.isInvalidPassword()) { setError("Incorrect password"); } else { setError( result.error?.errorData?.errorDescription || "An error occurred while verifying the password" ); } } if (result.isCompleted()) { setData(result.data); setSignInState(result.state); } } setLoading(false); };로그인 상태의
submitPassword()사용자 암호를 제출합니다.
등록 오류 처리
로그인하는 동안 모든 작업이 성공하는 것은 아닙니다. 예를 들어 사용자가 존재하지 않는 사용자 이름으로 로그인하거나 잘못된 전자 메일 일회용 암호 또는 최소 요구 사항을 충족하지 않는 암호를 제출하려고 할 수 있습니다. 다음과 같은 경우 오류를 올바르게 처리해야 합니다.
메서드에서 로그인 흐름을 시작합니다
signIn().메서드에서 일회성 암호를 제출합니다
submitCode().메서드에서 암호를 제출합니다
submitPassword(). 등록 흐름이 전자 메일 및 암호로 선택한 경우 이 오류를 처리합니다.
메서드signIn()에서 result.error?.isRedirectRequired() 발생할 수 있는 오류 중 하나는 . 이 시나리오는 네이티브 인증이 인증 흐름을 완료하기에 충분하지 않은 경우에 발생합니다. 예를 들어 권한 부여 서버에 클라이언트가 제공할 수 없는 기능이 필요한 경우입니다.
네이티브 인증 웹 대체 및 React 앱에서 웹 대체를 지원하는 방법에 대해 자세히 알아봅니다.
앱 실행 및 테스트
실행의 단계를 사용하고 앱을 테스트 하여 앱을 실행한 다음 로그인 흐름을 테스트합니다.
별칭 또는 사용자 이름으로 로그인 사용
전자 메일 주소 및 암호로 로그인하는 사용자가 사용자 이름 및 암호로 로그인하도록 허용할 수도 있습니다. 대체 로그인 식별자라고도 하는 사용자 이름은 고객 ID, 계정 번호 또는 사용자 이름으로 사용하도록 선택한 다른 식별자일 수 있습니다.
Microsoft Entra 관리 센터를 통해 사용자 계정에 사용자 이름을 수동으로 할당하거나 Microsoft Graph API를 통해 앱에서 사용자 이름을 자동화할 수 있습니다.
별칭 또는 사용자 이름으로 로그인하기 문서의 단계를 사용하여 사용자가 애플리케이션에서 사용자 이름으로 로그인할 수 있도록 합니다.
- 로그인에서 사용자 이름을 사용하도록 설정합니다.
- 관리 센터에서 사용자 이름을 가진 사용자를 만들 거나 사용자 이름을 추가하여 기존 사용자를 업데이트합니다. 또는 Microsoft Graph API를 사용하여 앱에서 사용자 만들기 및 업데이트를 자동화할 수도 있습니다.