적용 대상:
외부 테넌트(자세한 정보)
이 자습서에서는 네이티브 인증 JavaScript SDK를 사용하여 React 단일 페이지 앱에서 암호 재설정을 사용하도록 설정하는 방법을 알아봅니다.
이 자습서에서는 다음을 수행합니다.
- React 앱을 업데이트하여 사용자의 암호를 재설정합니다.
- 암호 재설정 흐름 테스트
필수 조건
- 자습서의 단계를 완료합니다. 네이티브 인증 JavaScript SDK를 사용하여 React 단일 페이지 앱에 사용자를 등록합니다.
- 외부 테넌트의 고객 사용자에 대해 SSPR(셀프 서비스 암호 재설정)을 사용하도록 설정합니다. SSPR은 암호 인증 흐름이 있는 전자 메일을 사용하는 앱에 대해 고객 사용자가 사용할 수 있습니다.
UI 구성 요소 만들기
암호 재설정 흐름 중에 이 앱은 다른 화면에서 사용자의 사용자 이름(이메일), 일회성 암호 및 새 사용자 암호를 수집합니다. 이 섹션에서는 앱이 암호를 재설정하는 데 필요한 정보를 수집하는 양식을 만듭니다.
src/app/reset-password라는 폴더를 만듭니다.
reset-password/components/InitialForm.tsx 파일을 만든 다음 reset-password/components/InitialForm.tsx의 코드를 붙여넣습니다. 이 구성 요소는 사용자의 사용자 이름(이메일)을 수집하는 양식을 표시합니다.
reset-password/components/CodeForm.tsx 파일을 만든 다음 reset-password/components/CodeForm.tsx의 코드를 붙여넣습니다. 이 구성 요소는 사용자가 전자 메일 받은 편지함에서 받는 일회용 암호를 수집하는 양식을 표시합니다.
reset-password/components/NewPasswordForm.tsx 파일을 만든 다음 reset-password/components/NewPasswordForm.tsx의 코드를 붙여넣습니다. 이 구성 요소는 사용자의 새 암호를 수집하는 양식을 표시합니다.
양식 상호 작용 처리
로그인 흐름에 대한 논리를 처리하는 reset-password/page.tsx 파일을 만듭니다. 이 파일에서 다음을 확인할 수 있습니다.
필요한 구성 요소를 가져오고 상태에 따라 적절한 양식을 표시합니다. reset-password/page.tsx의 전체 예제를 참조하세요.
import { CustomAuthPublicClientApplication, ICustomAuthPublicClientApplication, ResetPasswordCodeRequiredState, ResetPasswordPasswordRequiredState, ResetPasswordCompletedState, AuthFlowStateBase, } from "@azure/msal-browser/custom-auth"; export default function ResetPassword() { const [app, setApp] = useState<ICustomAuthPublicClientApplication | null>( null ); const [loadingAccountStatus, setLoadingAccountStatus] = useState(true); const [isSignedIn, setSignInState] = useState(false); const [email, setEmail] = useState(""); const [code, setCode] = useState(""); const [newPassword, setNewPassword] = useState(""); const [error, setError] = useState(""); const [loading, setLoading] = useState(false); const [resetState, setResetState] = useState<AuthFlowStateBase | null>( null ); useEffect(() => { const initializeApp = async () => { const appInstance = await CustomAuthPublicClientApplication.create( customAuthConfig ); setApp(appInstance); }; initializeApp(); }, []); useEffect(() => { const checkAccount = async () => { if (!app) return; const accountResult = app.getCurrentAccount(); if (accountResult.isCompleted()) { setSignInState(true); } setLoadingAccountStatus(false); }; checkAccount(); }, [app]); const renderForm = () => { if (loadingAccountStatus) { return; } if (isSignedIn) { return ( <div style={styles.signed_in_msg}> Please sign out before processing the password reset. </div> ); } if (resetState instanceof ResetPasswordPasswordRequiredState) { return ( <NewPasswordForm onSubmit={handleNewPasswordSubmit} newPassword={newPassword} setNewPassword={setNewPassword} loading={loading} /> ); } if (resetState instanceof ResetPasswordCodeRequiredState) { return ( <CodeForm onSubmit={handleCodeSubmit} code={code} setCode={setCode} loading={loading} /> ); } if (resetState instanceof ResetPasswordCompletedState) { return <ResetPasswordResultPage />; } return ( <InitialForm onSubmit={handleInitialSubmit} email={email} setEmail={setEmail} loading={loading} /> ); }; return ( <div style={styles.container}> <h2 style={styles.h2}>Reset Password</h2> {renderForm()} {error && <div style={styles.error}>{error}</div>} </div> ); }암호 재설정 흐름을 시작하려면 다음 코드 조각을 사용합니다. 코드 조각을 배치할 위치를 알아보려면 reset-password/page.tsx 의 전체 예제를 참조하세요.
const handleInitialSubmit = async (e: React.FormEvent) => { if (!app) return; e.preventDefault(); setError(""); setLoading(true); const result = await app.resetPassword({ username: email, }); const state = result.state; if (result.isFailed()) { if (result.error?.isInvalidUsername()) { setError("Invalid email address"); } else if (result.error?.isUserNotFound()) { setError("User not found"); } else { setError( result.error?.errorData.errorDescription || "An error occurred while initiating password reset" ); } } else { setResetState(state); } setLoading(false); };SDK의 인스턴스 메서드는
resetPassword()암호 재설정 흐름을 시작합니다.일회성 암호를 제출하려면 다음 코드 조각을 사용합니다. 코드 조각을 배치할 위치를 알아보려면 reset-password/page.tsx 의 전체 예제를 참조하세요.
const handleCodeSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(""); setLoading(true); if (resetState instanceof ResetPasswordCodeRequiredState) { const result = await resetState.submitCode(code); const state = result.state; if (result.isFailed()) { if (result.error?.isInvalidCode()) { setError("Invalid verification code"); } else { setError(result.error?.errorData.errorDescription || "An error occurred while verifying the code"); } } else { setResetState(state); } } setLoading(false); };암호 재설정 상태는
submitCode()일회성 암호를 제출합니다.사용자의 새 암호를 제출하려면 다음 코드 조각을 사용합니다. 코드 조각을 배치할 위치를 알아보려면 reset-password/page.tsx 의 전체 예제를 참조하세요.
const handleNewPasswordSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(""); setLoading(true); if (resetState instanceof ResetPasswordPasswordRequiredState) { const result = await resetState.submitNewPassword(newPassword); const state = result.state; if (result.isFailed()) { if (result.error?.isInvalidPassword()) { setError("Invalid password"); } else { setError(result.error?.errorData.errorDescription || "An error occurred while setting new password"); } } else { setResetState(state); } } setLoading(false); };암호 재설정 상태는
submitNewPassword()사용자의 새 암호를 제출합니다.암호 재설정 결과를 사용하려면 다음 코드 조각을 사용합니다. 코드 조각을 배치할 위치를 알아보려면 reset-password/page.tsx 의 전체 예제를 참조하세요.
if (resetState instanceof ResetPasswordCompletedState) { return <ResetPasswordResultPage/>; }
선택 사항: 암호 재설정 후 자동으로 사용자 로그인
사용자가 암호를 성공적으로 재설정한 후에는 새 로그인 흐름을 시작하지 않고 앱에 직접 로그인할 수 있습니다. 이렇게 하려면 다음 코드 조각을 사용합니다. reset-password/page.tsx에서 전체 예제를 참조하세요.
if (resetState instanceof ResetPasswordCompletedState) {
const result = await resetState.signIn();
const state = result.state;
if (result.isFailed()) {
setError(result.error?.errorData?.errorDescription || "An error occurred during auto sign-in");
}
if (result.isCompleted()) {
setData(result.data);
setResetState(state);
}
}
앱 실행 및 테스트
실행의 단계를 사용하고 앱을 테스트 하여 앱을 실행한 다음 로그인 흐름을 테스트합니다.