Dela via


Självstudie: Logga in användare i en React-enkelsidig app med hjälp av inbyggd autentisering med JavaScript SDK

Gäller för: Grön cirkel med en vit bockmarkeringssymbol som anger att följande innehåll gäller för externa klienter. Externa klienter (läs mer)

I den här självstudien får du lära dig hur du loggar in användare i en React-ensidesapp (SPA) med hjälp av inbyggd autentisering med JavaScript SDK.

I den här handledningen kommer du att:

  • Uppdatera en React-app för att logga in användare.
  • Testa inloggningsflödet.

Förutsättningar

Skapa gränssnittskomponenter

I det här avsnittet skapar du formuläret som samlar in användarens inloggningsinformation:

  1. Skapa en mapp med namnet src/app/sign-in.

  2. Skapa inloggnings-/komponenter/InitialForm.tsx-fil och klistra sedan in koden från inloggning/komponenter/InitialForm.tsx. Den här komponenten visar ett formulär som samlar in en användares användarnamn (e-post).

  3. Om ditt val av autentiseringsmetod är e-post och engångslösenord skapar du en inloggnings-/komponenter/CodeForm.tsx-fil och klistrar sedan in koden från inloggning/komponenter/CodeForm.tsx. Om administratören anger engångslösenord för e-post som inloggningsflöde i administrationscentret för Microsoft Entra, visar den här komponenten ett formulär för att samla in engångslösenordet från användaren.

  4. Om ditt val av autentiseringsmetod är e-post och lösenord skapar du en inloggnings-/komponenter/PasswordForm.tsx-fil och klistrar sedan in koden från inloggning/komponenter/PasswordForm.tsx. Den här komponenten visar ett formulär som samlar in en användares lösenord.

  5. Skapa en inloggnings-/komponenter/UserInfo.tsx-fil och klistra sedan in koden från inloggning/komponenter/UserInfo.tsx. Den här komponenten visar en inloggad användares användarnamn och inloggningsstatus.

Hantera formulärinteraktioner

I det här avsnittet lägger du till kod som hanterar interaktioner med inloggningsformulär, till exempel att starta ett inloggningsflöde, skicka användarlösenord eller ett engångslösenord.

Skapa en inloggnings-/page.tsx-fil för att hantera logik för ett inloggningsflöde. I den här filen:

  • Importera nödvändiga komponenter och visa rätt formulär baserat på tillståndet. Se ett fullständigt exempel på inloggning/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>
        );
    }
    
  • Starta inloggningsflödet genom att använda följande kodfragment. Se ett fullständigt exempel på inloggning/page.tsx för att lära dig var kodfragmentet ska placeras:

    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:s instansmetod, signIn(), startar inloggningsflödet.

  • Om ditt val av autentiseringsflöde är e-post och engångslösenord skickar du engångslösenordet med hjälp av följande kodfragment. Se ett fullständigt exempel på inloggning/page.tsx för att lära dig var kodfragmentet ska placeras:

    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);
    };
    

    Inloggningstillståndet submitCode() skickar engångslösenordet.

  • Om ditt val av autentiseringsflöde är e-post och lösenord skickar du användarens lösenord med hjälp av följande kodfragment. Se ett fullständigt exempel på inloggning/page.tsx för att lära dig var kodfragmentet ska placeras:

    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);
    };
    

    Inloggningstillståndet submitPassword() skickar användarens lösenord.

Hantera problem med registrering

Under inloggningen lyckas inte alla åtgärder. Användaren kan till exempel försöka logga in med ett användarnamn som inte finns eller skicka ett ogiltigt engångslösenord för e-post eller ett lösenord som inte uppfyller minimikraven. Kontrollera att du hanterar fel korrekt när du:

  • Starta inloggningsflödet i signIn() -metoden.

  • Skicka engångslösenordet submitCode() i metoden.

  • Skicka lösenord i submitPassword() -metoden. Du hanterar det här felet om ditt val av registreringsflöde sker via e-post och lösenord.

Ett av de fel som kan uppstå från signIn() metoden är result.error?.isRedirectRequired(). Det här scenariot inträffar när intern autentisering inte räcker för att slutföra autentiseringsflödet. Om auktoriseringsservern till exempel kräver funktioner som klienten inte kan tillhandahålla. Läs mer om webbåterställning för intern autentisering och hur du stöder webbåterställning i react-appen.

Köra och testa din app

Använd stegen i Kör och testa din app för att köra din app och testa sedan inloggningsflödet.