Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
S’applique à :
Locataires externes (en savoir plus)
Dans ce tutoriel, vous allez apprendre à créer une application à page unique React qui inscrit des utilisateurs à l’aide du Kit de développement logiciel (SDK) JavaScript de l’authentification native.
Dans ce tutoriel, vous allez :
- Créez un projet React Next.js.
- Ajoutez le Kit de développement logiciel (SDK) MSAL JS à celui-ci.
- Ajoutez des composants d’interface utilisateur de l’application.
- Configurez le projet pour inscrire des utilisateurs.
Conditions préalables
- Suivez les étapes de Démarrage rapide : Connecter des utilisateurs dans une application React à page unique à l’aide du kit de développement logiciel (SDK) JavaScript d’authentification native. Ce guide de démarrage rapide vous montre comment exécuter un exemple de code React.
- Effectuez les étapes décrites dans Configurer le serveur proxy CORS pour gérer les en-têtes CORS pour l’authentification native.
- Visual Studio Code ou un autre éditeur de code.
- Node.js.
Créer un projet React et installer des dépendances
Dans un emplacement de choix dans votre ordinateur, exécutez les commandes suivantes pour créer un projet React avec le nom reactspa, accédez au dossier du projet, puis installez les packages :
npx create-next-app@latest
cd reactspa
npm install
Une fois que vous avez correctement exécuté les commandes, vous devez disposer d’une application avec la structure suivante :
spasample/
└──node_modules/
└──...
└──public/
└──...
└──src/
└──app/
└──favicon.ico
└──globals.css
└──page.tsx
└──layout.tsx
└──postcss.config.mjs
└──package-lock.json
└──package.json
└──tsconfig.json
└──README.md
└──next-env.d.ts
└──next.config.ts
Ajouter le Kit de développement logiciel (SDK) JavaScript à votre projet
Pour utiliser le Kit de développement logiciel (SDK) JavaScript d’authentification native dans votre application, utilisez votre terminal pour l’installer à l’aide de la commande suivante :
npm install @azure/msal-browser
Les fonctionnalités d’authentification native font partie de la azure-msal-browser bibliothèque. Pour utiliser les fonctionnalités d’authentification native, vous importez à partir de @azure/msal-browser/custom-auth. Par exemple:
import CustomAuthPublicClientApplication from "@azure/msal-browser/custom-auth";
Ajouter une configuration du client
Dans cette section, vous définissez une configuration pour l’application cliente publique d’authentification native pour lui permettre d’interagir avec l’interface du Kit de développement logiciel (SDK). Pour ce faire, créez un fichier appelé src/config/auth-config.ts, puis ajoutez le code suivant :
export const customAuthConfig: CustomAuthConfiguration = {
customAuth: {
challengeTypes: ["password", "oob", "redirect"],
authApiProxyUrl: "http://localhost:3001/api",
},
auth: {
clientId: "Enter_the_Application_Id_Here",
authority: "https://Enter_the_Tenant_Subdomain_Here.ciamlogin.com",
redirectUri: "/",
postLogoutRedirectUri: "/",
navigateToLoginRequestUrl: false,
},
cache: {
cacheLocation: "sessionStorage",
},
system: {
loggerOptions: {
loggerCallback: (
level: LogLevel,
message: string,
containsPii: boolean
) => {
if (containsPii) {
return;
}
switch (level) {
case LogLevel.Error:
console.error(message);
return;
case LogLevel.Info:
console.info(message);
return;
case LogLevel.Verbose:
console.debug(message);
return;
case LogLevel.Warning:
console.warn(message);
return;
}
},
},
},
};
Dans le code, recherchez l’espace réservé :
Enter_the_Application_Id_Hereremplacez-la par l’ID d’application (client) de l’application que vous avez inscrite précédemment.Enter_the_Tenant_Subdomain_Hereremplacez-le par le sous-domaine du locataire dans votre centre d’administration Microsoft Entra. Par exemple, si le domaine principal de votre locataire estcontoso.onmicrosoft.com, utilisezcontoso. Si vous ne disposez pas du nom de votre locataire, découvrez de quelle manière consulter les détails de votre locataire.
Créer des composants d’interface utilisateur
Cette application collecte les détails de l’utilisateur, tels que le nom donné, le nom d’utilisateur (e-mail), le mot de passe et un code secret à usage unique de l’utilisateur. Par conséquent, l’application doit avoir un formulaire qui collecte ces informations.
Créez un dossier appelé src/app/sign-up dans le dossier src .
Créez le fichier sign-up/components/InitialForm.tsx, puis collez le code de sign-up/components/InitialForm.tsx. Ce composant affiche un formulaire qui collecte les attributs d’inscription de l’utilisateur.
Créez un fichier d’inscription/components/CodeForm.tsx , puis collez le code de l’inscription/components/CodeForm.tsx. Ce composant affiche un formulaire qui collecte un code secret unique envoyé à l’utilisateur. Vous avez besoin de ce formulaire pour l’e-mail avec mot de passe ou e-mail avec une méthode d’authentification par code secret à usage unique.
Si votre choix de méthode d’authentification est e-mail avec mot de passe, créez un fichier d’inscription/components/PasswordForm.tsx , puis collez le code de l’inscription/components/PasswordForm.tsx. Ce composant affiche un formulaire d’entrée de mot de passe.
Gérer les interactions avec le formulaire
Dans cette section, vous ajoutez du code qui gère les interactions de formulaire d’inscription, telles que l’envoi de détails d’inscription de l’utilisateur ou un code secret à usage unique ou un mot de passe.
Créez sign-up/page.tsx pour gérer la logique du flux d'inscription. Dans ce fichier :
Importez les composants nécessaires et affichez le formulaire approprié en fonction de l’état. Consultez un exemple complet dans sign-up/page.tsx :
import { useEffect, useState } from "react"; import { customAuthConfig } from "../../config/auth-config"; import { styles } from "./styles/styles"; import { InitialFormWithPassword } from "./components/InitialFormWithPassword"; import { CustomAuthPublicClientApplication, ICustomAuthPublicClientApplication, SignUpCodeRequiredState, // Uncomment if your choice of authentication method is email with password // SignUpPasswordRequiredState, SignUpCompletedState, AuthFlowStateBase, } from "@azure/msal-browser/custom-auth"; import { SignUpResultPage } from "./components/SignUpResult"; import { CodeForm } from "./components/CodeForm"; import { PasswordForm } from "./components/PasswordForm"; export default function SignUpPassword() { const [authClient, setAuthClient] = useState<ICustomAuthPublicClientApplication | null>(null); const [firstName, setFirstName] = useState(""); const [lastName, setLastName] = useState(""); const [jobTitle, setJobTitle] = useState(""); const [city, setCity] = useState(""); const [country, setCountry] = useState(""); const [email, setEmail] = useState(""); //Uncomment if your choice of authentication method is email with password //const [password, setPassword] = useState(""); const [code, setCode] = useState(""); const [error, setError] = useState(""); const [loading, setLoading] = useState(false); const [signUpState, setSignUpState] = useState<AuthFlowStateBase | null>(null); const [loadingAccountStatus, setLoadingAccountStatus] = useState(true); const [isSignedIn, setSignInState] = 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()) { setSignInState(true); } setLoadingAccountStatus(false); }; checkAccount(); }, [authClient]); const renderForm = () => { if (loadingAccountStatus) { return; } if (isSignedIn) { return ( <div style={styles.signed_in_msg}>Please sign out before processing the sign up.</div> ); } if (signUpState instanceof SignUpCodeRequiredState) { return ( <CodeForm onSubmit={handleCodeSubmit} code={code} setCode={setCode} loading={loading} /> ); } //Uncomment the following block of code if your choice of authentication method is email with password /* else if(signUpState instanceof SignUpPasswordRequiredState) { return <PasswordForm onSubmit={handlePasswordSubmit} password={password} setPassword={setPassword} loading={loading} />; } */ else if (signUpState instanceof SignUpCompletedState) { return <SignUpResultPage />; } else { return ( <InitialForm onSubmit={handleInitialSubmit} firstName={firstName} setFirstName={setFirstName} lastName={lastName} setLastName={setLastName} jobTitle={jobTitle} setJobTitle={setJobTitle} city={city} setCity={setCity} country={country} setCountry={setCountry} email={email} setEmail={setEmail} loading={loading} /> ); } } return ( <div style={styles.container}> <h2 style={styles.h2}>Sign Up</h2> {renderForm()} {error && <div style={styles.error}>{error}</div>} </div> ); }Ce code crée également une instance de l’application cliente publique d’authentification native à l’aide de la configuration du client :
const appInstance = await CustomAuthPublicClientApplication.create(customAuthConfig); setAuthClient(appInstance);Pour gérer la soumission initiale du formulaire, utilisez l’extrait de code suivant. Consultez un exemple complet à inscription/page.tsx pour savoir où placer l'extrait de code :
const handleInitialSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(""); setLoading(true); if (!authClient) return; const attributes: UserAccountAttributes = { displayName: `${firstName} ${lastName}`, givenName: firstName, surname: lastName, jobTitle: jobTitle, city: city, country: country, }; const result = await authClient.signUp({ username: email, attributes }); const state = result.state; if (result.isFailed()) { if (result.error?.isUserAlreadyExists()) { setError("An account with this email already exists"); } else if (result.error?.isInvalidUsername()) { setError("Invalid uername"); } else if (result.error?.isInvalidPassword()) { setError("Invalid password"); } else if (result.error?.isAttributesValidationFailed()) { setError("Invalid attributes"); } else if (result.error?.isMissingRequiredAttributes()) { setError("Missing required attributes"); } else { setError(result.error?.errorData.errorDescription || "An error occurred while signing up"); } } else { setSignUpState(state); } setLoading(false); };La méthode d’instance du Kit de développement logiciel (SDK)
signUp()démarre le flux d’inscription.Pour gérer la soumission de code secret unique, utilisez l’extrait de code suivant. Consultez un exemple complet à inscription/page.tsx pour savoir où placer l'extrait de code :
const handleCodeSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(""); setLoading(true); try { if (signUpState instanceof SignUpCodeRequiredState) { const result = await signUpState.submitCode(code); if (result.error) { if (result.error.isInvalidCode()) { setError("Invalid verification code"); } else { setError("An error occurred while verifying the code"); } return; } if (result.state instanceof SignUpCompletedState) { setSignUpState(result.state); } } } catch (err) { setError("An unexpected error occurred"); console.error(err); } finally { setLoading(false); } };Pour gérer la soumission de mot de passe, utilisez l’extrait de code suivant. Vous gérez la soumission de mot de passe si votre choix de méthode d’authentification est un e-mail avec mot de passe. Consultez un exemple complet à inscription/page.tsx pour savoir où placer l'extrait de code :
const handlePasswordSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(""); setLoading(true); if (signUpState instanceof SignUpPasswordRequiredState) { const result = await signUpState.submitPassword(password); const state = result.state; if (result.isFailed()) { if (result.error?.isInvalidPassword()) { setError("Invalid password"); } else { setError(result.error?.errorData.errorDescription || "An error occurred while submitting the password"); } } else { setSignUpState(state); } } setLoading(false); };Utilisez la
signUpState instanceof SignUpCompletedStatecommande pour indiquer que l’utilisateur a été inscrit et que le flux est terminé. Consultez un exemple complet à sign-up/page.tsx :if (signUpState instanceof SignUpCompletedState) { return <SignUpResultPage/>; }
Gérer les erreurs d’inscription
Pendant l’inscription, toutes les actions n’aboutissent pas. Par exemple, l’utilisateur peut tenter de s’inscrire avec une adresse e-mail déjà utilisée, ou soumettre un code secret à usage unique envoyé par e-mail non valide. Vérifiez que vous gérez correctement les erreurs lorsque vous :
Lancez le flux d'inscription avec la méthode
signUp().Envoyez le code d'accès unique par la méthode
submitCode().Envoyez le mot de passe dans la
submitPassword()méthode. Vous gérez cette erreur si votre choix de flux d’inscription est par e-mail et par mot de passe.
L’une des erreurs pouvant résulter de la signUp() méthode est result.error?.isRedirectRequired(). Ce scénario se produit quand l’authentification native n’est pas suffisante pour effectuer le flux d’authentification. Par exemple, si le serveur d’autorisation nécessite des fonctionnalités que le client ne peut pas fournir. En savoir plus sur le repli web pour l'authentification native et sur la prise en charge du repli web dans votre application React.
Facultatif : Connecter automatiquement les utilisateurs après l’inscription
Une fois qu’un utilisateur s’est correctement inscrit, vous pouvez directement les connecter à l’application sans lancer de nouveau flux de connexion. Pour ce faire, utilisez l’extrait de code suivant. Consultez un exemple complet à sign-up/page.tsx :
if (signUpState instanceof SignUpCompletedState) {
const result = await signUpState.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);
setSignUpState(state);
}
}
Exécuter et tester votre application
Ouvrez une fenêtre de terminal et accédez au dossier racine de votre application :
cd reactspaPour démarrer le serveur proxy CORS, exécutez la commande suivante dans votre terminal :
npm run corsPour démarrer l’application React, ouvrez une autre fenêtre de terminal, puis exécutez la commande suivante :
cd reactspa npm startOuvrez un navigateur web et accédez à
http://localhost:3000/sign-up. Un formulaire d’inscription s’affiche.Pour vous inscrire à un compte, entrez vos détails, sélectionnez le bouton Continuer , puis suivez les invites.
Ensuite, vous pouvez mettre à jour l’application React pour vous connecter à un utilisateur ou réinitialiser le mot de passe de l’utilisateur.
Configurer poweredByHeader sur false dans next.config.js
Par défaut, l’en-tête x-powered-by est inclus dans les réponses HTTP pour indiquer que l’application est alimentée par Next.js. Toutefois, pour des raisons de sécurité ou de personnalisation, vous pouvez supprimer ou modifier cet en-tête :
const nextConfig: NextConfig = {
poweredByHeader: false,
/* other config options here */
};