適用於:
外部租用戶 (深入瞭解)
在本教學課程中,您將瞭解如何使用原生驗證 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);
}
}
執行及測試您的應用程式
使用 執行和測試應用程式 中的步驟來執行您的應用程式,然後測試登入流程。