Partilhar via


Tutorial: Entrar usuários em um aplicativo de página única do React usando o SDK JavaScript de autenticação nativa

Aplica-se a: círculo verde com um símbolo de marca de seleção branco que indica que o conteúdo a seguir se aplica a locatários externos. Inquilinos externos (saiba mais)

Neste tutorial, você aprenderá a fazer login de usuários em um aplicativo de página única (SPA) React usando o SDK JavaScript de autenticação nativa.

Neste tutorial, você:

  • Atualize uma aplicação React para iniciar sessão de utilizadores.
  • Teste o fluxo de entrada.

Pré-requisitos

Criar componentes da interface do usuário

Nesta seção, você cria o formulário que coleta as informações de entrada do usuário:

  1. Crie uma pasta chamada src/app/sign-in.

  2. Crie o arquivo sign-in/components/InitialForm.tsx e cole o código de sign-in/components/InitialForm.tsx. Este componente exibe um formulário que coleta o nome de usuário (e-mail) de um usuário.

  3. Se a sua escolha de método de autenticação for e-mail e código de acesso único, crie um arquivo de entrada/componentes/CodeForm.tsx e, em seguida, cole o código de login/components/CodeForm.tsx. Se o administrador definir a senha única de email como o fluxo de entrada no centro de administração do Microsoft Entra, esse componente exibirá um formulário para coletar a senha única do usuário.

  4. Se a sua escolha de método de autenticação for e-mail e senha, crie um arquivo de login/components/PasswordForm.tsx e cole o código de login/components/PasswordForm.tsx. Este componente exibe um formulário que coleta a senha de um usuário.

  5. Crie um ficheiro de início de sessão/components/UserInfo.tsx e, em seguida, cole o código de início de sessão/components/UserInfo.tsx. Este componente apresenta o nome de utilizador com sessão iniciada e o estado de início de sessão.

Manipular interações de formulário

Nesta seção, você adiciona código que lida com interações de formulário de entrada, como iniciar um fluxo de entrada, enviar senha de usuário ou uma senha de uso único.

Crie um arquivo de entrada/page.tsx para manipular a lógica de um fluxo de entrada. Neste ficheiro:

  • Importe os componentes necessários e exiba o formulário adequado com base no estado. Veja um exemplo completo em 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 o fluxo de entrada, use o seguinte trecho de código. Veja um exemplo completo em sign-in/page.tsx para saber onde colocar o trecho 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);
    };
    

    O método de instância do SDK, signIn(), inicia o fluxo de entrada.

  • Se a sua escolha de fluxo de autenticação for e-mail e senha única, envie a senha única usando o trecho de código a seguir. Veja um exemplo completo em sign-in/page.tsx para saber onde colocar o trecho 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);
    };
    

    O estado de submitCode() login envia a senha única.

  • Se sua escolha de fluxo de autenticação for e-mail e senha, envie a senha do usuário usando o trecho de código a seguir. Veja um exemplo completo em sign-in/page.tsx para saber onde colocar o trecho 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);
    };
    

    O estado de submitPassword() login envia a senha do usuário.

Lidar com erros de inscrição

Ao iniciar sessão, não são todas as ações que têm sucesso. Por exemplo, o usuário pode tentar entrar com um nome de usuário que não existe ou enviar uma senha única de e-mail inválida ou uma senha que não atenda aos requisitos mínimos. Certifique-se de lidar com os erros corretamente quando:

  • Inicie o signIn() fluxo de entrada no método.

  • Envie a senha única no submitCode() método.

  • Envie a senha no submitPassword() método. Você lida com esse erro se sua escolha de fluxo de inscrição for por e-mail e senha.

Um dos erros que podem resultar do signIn() método é result.error?.isRedirectRequired(). Esse cenário acontece quando a autenticação nativa não é suficiente para concluir o fluxo de autenticação. Por exemplo, se o servidor de autorização exigir recursos que o cliente não pode fornecer. Saiba mais sobre o fallback da Web de autenticação nativa e como dar suporte ao fallback da Web em seu aplicativo React.

Executar e testar seu aplicativo

Use as etapas em Executar e testar seu aplicativo para executar seu aplicativo e, em seguida, teste o fluxo de entrada.

Ative o início de sessão com um alias ou nome de utilizador

Pode permitir que os utilizadores que iniciam sessão com um endereço de e-mail e palavra-passe também iniciem sessão com um nome de utilizador e palavra-passe. O nome de utilizador, também chamado de identificador alternativo de entrada, pode ser um ID de cliente, número de conta ou outro identificador que escolha usar como nome de utilizador.

Pode atribuir nomes de utilizador manualmente à conta de utilizador através do centro de administração do Microsoft Entra ou automatizá-lo na sua aplicação através da API Microsoft Graph.

Use os passos no artigo Iniciar sessão com um alias ou nome de utilizador para permitir que os seus utilizadores iniciem sessão usando um nome de utilizador na aplicação:

  1. Ativar o nome de utilizador no início de sessão.
  2. Crie utilizadores com nome de utilizador no centro de administração ou atualize utilizadores existentes adicionando um nome de utilizador. Alternativamente, pode também automatizar a criação e atualização de utilizadores na sua aplicação usando a Microsoft Graph API.