Compartilhar via


Tutorial: Conectar 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 branca que indica que o conteúdo a seguir se aplica a locatários externos. Locatários externos (saiba mais)

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

Neste tutorial, você:

  • Atualize um aplicativo React para conectar usuários.
  • Teste o fluxo de entrada.

Pré-requisitos

Criar componentes de interface do usuário

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

  1. Crie uma pasta chamada src/app/login.

  2. Crie entrada/componentes/arquivo InitialForm.tsx e cole o código de entrada/componentes/InitialForm.tsx. Esse componente exibe um formulário que coleta o nome de usuário (email) de um usuário.

  3. Se sua opção de método de autenticação for email e senha única, crie um arquivo de entrada/componentes/CodeForm.tsx e cole o código de entrada/componentes/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 sua opção de método de autenticação for email e senha, crie um arquivo PasswordForm.tsx/login/components/PasswordForm.tsx e cole o código de entrada/componentes/PasswordForm.tsx. Esse componente exibe um formulário que coleta a senha de um usuário.

  5. Crie um arquivo de entrada/componentes/UserInfo.tsx e cole o código de entrada/componentes/UserInfo.tsx. Esse componente exibe o nome de usuário e o status de entrada de um usuário conectado.

Manipular interações de formulário

Nesta seção, você adicionará um código que manipula interações de formulário de entrada, como iniciar um fluxo de entrada, enviar senha de usuário ou uma senha única.

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

  • Importe os componentes necessários e exiba o formulário adequado com base no estado. Veja um exemplo completo de entrada/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 snippet de código a seguir. Veja um exemplo completo em login/page.tsx para saber onde colocar o snippet 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 signIn()de instância do SDK inicia o fluxo de entrada.

  • Se sua opção de fluxo de autenticação for email e senha única, envie a senha única usando o snippet de código a seguir. Veja um exemplo completo em login/page.tsx para saber onde colocar o snippet 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() entrada envia a senha única.

  • Se sua opção de fluxo de autenticação for email e senha, envie a senha do usuário usando o snippet de código a seguir. Veja um exemplo completo em login/page.tsx para saber onde colocar o snippet 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() entrada envia a senha do usuário.

Tratar erros de inscrição

Durante o login, nem todas as ações são bem-sucedidas. Por exemplo, o usuário pode tentar entrar com um nome de usuário que não existe ou enviar uma senha única de email inválida ou uma senha que não atenda aos requisitos mínimos. Verifique se você lida com erros corretamente ao:

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

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

  • Enviar senha no submitPassword() método. Você lidará com esse erro se sua opção de fluxo de inscrição for por email e senha.

Um dos erros que podem resultar do signIn() método é result.error?.isRedirectRequired(). Esse cenário ocorre 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 teste seu aplicativo para executar seu aplicativo e teste o fluxo de entrada.

Habilitar o login com um alias ou nome de usuário

Você pode permitir que os usuários que entrarem com um endereço de email e senha também entrem com um nome de usuário e senha. O nome de usuário também chamado de identificador de entrada alternativo pode ser uma ID do cliente, um número de conta ou outro identificador que você escolhe usar como nome de usuário.

Você pode atribuir nomes de usuário à conta de usuário manualmente por meio do Centro de administração do Microsoft Entra ou automatizá-la em seu aplicativo por meio da API do Microsoft Graph.

Use as etapas no artigo Entrar com um alias ou nome de usuário para permitir que os usuários façam login usando um nome de usuário no seu aplicativo.

  1. Habilitar nome de usuário no login.
  2. Crie usuários com nome de usuário no centro de administração ou atualize os usuários existentes adicionando um nome de usuário. Como alternativa, você também pode automatizar a criação e a atualização do usuário em seu aplicativo usando a API do Microsoft Graph.