Compartir a través de


Tutorial: Inicio de sesión de usuarios en una aplicación de página única de React mediante el SDK de JavaScript de autenticación nativa

Se aplica a: Círculo verde con un símbolo de marca de verificación blanca que indica que el siguiente contenido se aplica a los inquilinos externos. Inquilinos externos (más información)

En este tutorial, aprenderá a iniciar sesión de los usuarios en una aplicación de página única (SPA) de React mediante el SDK de JavaScript de autenticación nativa.

En este tutorial, usted hará lo siguiente:

  • Actualice una aplicación react para iniciar sesión de los usuarios.
  • Pruebe el flujo de inicio de sesión.

Prerrequisitos

Creación de componentes de interfaz de usuario

En esta sección, creará el formulario que recopila la información de inicio de sesión del usuario:

  1. Cree una carpeta denominada src/app/sign-in.

  2. Cree el archivo sign-in/components/InitialForm.tsx y luego pegue el código de sign-in/components/InitialForm.tsx. Este componente muestra un formulario que recopila el nombre de usuario (correo electrónico) de un usuario.

  3. Si su elección del método de autenticación es el correo electrónico y el código de acceso de un solo uso, cree un archivo sign-in/components/CodeForm.tsx y pegue el código de sign-in/components/CodeForm.tsx. Si el administrador establece el código de acceso de un solo uso de correo electrónico como flujo de inicio de sesión en el Centro de administración de Microsoft Entra, este componente muestra un formulario para recopilar el código de acceso de un solo uso del usuario.

  4. Si su elección del método de autenticación es correo electrónico y contraseña, cree un archivo sign-in/components/PasswordForm.tsx y pegue el código de sign-in/components/PasswordForm.tsx. Este componente muestra un formulario que recopila la contraseña de un usuario.

  5. Cree un archivo sign-in/components/UserInfo.tsx y pegue el código de sign-in/components/UserInfo.tsx. Este componente muestra el nombre de usuario y el estado de inicio de sesión del usuario que ha iniciado sesión.

Controlar las interacciones del formulario

En esta sección, agregará código que controla las interacciones del formulario de inicio de sesión, como iniciar un flujo de inicio de sesión, enviar contraseña de usuario o un código de acceso de un solo uso.

Cree un archivo sign-in/page.tsx para controlar la lógica de un flujo de inicio de sesión. En este archivo:

  • Importe los componentes necesarios y muestre el formulario adecuado en función del estado. Vea un ejemplo completo en sign-in/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>
        );
    }
    
  • Para iniciar el flujo de inicio de sesión, use el siguiente fragmento de código. Vea un ejemplo completo en sign-in/page.tsx para obtener información sobre dónde colocar el fragmento de código:

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

    El método de instancia del SDK, signIn(), inicia el flujo de inicio de sesión.

  • Si su elección del flujo de autenticación es el correo electrónico y el código de acceso de un solo uso, envíe el código de acceso de un solo uso mediante el siguiente fragmento de código. Vea un ejemplo completo en sign-in/page.tsx para obtener información sobre dónde colocar el fragmento de código:

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

    El estado de inicio de submitCode() sesión envía el código de acceso de un solo uso.

  • Si su elección del flujo de autenticación es el correo electrónico y la contraseña, envíe la contraseña del usuario mediante el siguiente fragmento de código. Vea un ejemplo completo en sign-in/page.tsx para obtener información sobre dónde colocar el fragmento de código:

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

    El estado de submitPassword() de inicio de sesión envía la contraseña del usuario.

Manejo de errores de inscripción

Durante el inicio de sesión, no todas las acciones se realizan correctamente. Por ejemplo, el usuario podría intentar iniciar sesión con un nombre de usuario que no existe o enviar un código de acceso de un solo uso de correo electrónico no válido o una contraseña que no cumpla los requisitos mínimos. Asegúrese de controlar los errores correctamente cuando:

  • Inicie el flujo de inicio de sesión en el método signIn().

  • Envíe el código de acceso de un solo uso en el método submitCode().

  • Envíe la contraseña en el método submitPassword(). Usted maneja este error si elige el flujo de registro por correo electrónico y contraseña.

Uno de los errores que puede resultar del signIn() método es result.error?.isRedirectRequired(). Este escenario se produce cuando la autenticación nativa no es suficiente para completar el flujo de autenticación. Por ejemplo, si el servidor de autorización requiere funcionalidades que el cliente no puede proporcionar. Obtenga más información sobre la alternativa web de autenticación nativa y cómo admitir la alternativa web en su aplicación de React.

Ejecución y prueba de la aplicación

Siga los pasos descritos en Ejecución y prueba de la aplicación para ejecutar la aplicación y, a continuación, pruebe el flujo de inicio de sesión.

Habilitación del inicio de sesión con un alias o un nombre de usuario

Puede permitir que los usuarios que inicien sesión con una dirección de correo electrónico y una contraseña también inicien sesión con un nombre de usuario y una contraseña. El nombre de usuario también denominado identificador de inicio de sesión alternativo puede ser un identificador de cliente, un número de cuenta u otro identificador que elija usar como nombre de usuario.

Puede asignar nombres de usuario a la cuenta de usuario manualmente a través del Centro de administración de Microsoft Entra o automatizarlo en la aplicación a través de Microsoft Graph API.

Siga los pasos descritos en el artículo Iniciar sesión con un alias o nombre de usuario para permitir que los usuarios inicien sesión con un nombre de usuario en su aplicación.

  1. Habilite el nombre de usuario en el inicio de sesión.
  2. Cree usuarios con el nombre de usuario en el Centro de administración o actualice los usuarios existentes a agregando un nombre de usuario. Como alternativa, también puede automatizar la creación y actualización de usuarios en la aplicación mediante Microsoft Graph API.