Créez une connexion sans mot de passe pour les SMS et les courriels
Before you start
Vous avez besoin de ce qui suit :
Un locataire de développement Auth0 avec la connexion universelle configurée.
Une application configurée de domaine personnalisé.
Une app de développement ou d’exemple (comme React sample) s’exécutant sur votre localhost.
Une connexion de base de données qui utilise une connexion sans mot de passe.
À la fin de ce flux, vous disposerez d’un écran de connexion sans mot de passe personnalisé avec l’option liée aux courriels ou aux SMS.
Pour en savoir plus, lisez le Guide de démarrage et consultez le Guide de référence de la trousse SDK.
Configuration
Dans votre Auth0 Dashboard, configurez la connexion universelle, l’authentification Identifier First, et une connexion à la base de données qui utilise des mots de passe.
Exécutez une application à page unique pour créer des écrans de connexion personnalisés. Pour comprendre le contexte des interfaces de personnalisations avancées, clonez notre application de base : git clone https://github.com/auth0/auth0-acul-react-boilerplate
Installez la trousse SDK ACUL. Après avoir cloné le composant React réutilisable, changez le répertoire vers le dossier auth0-acul-react-boilerplate
et installez la trousse SDK.
//Clone the ACUL sample application into the root folder of your project
git clone https://github.com/auth0-samples/auth0-acul-samples.git
//Change directory to install the ACUL sample application
cd auth0-acul-samples && npm i
Was this helpful?
Option 1 : Créez l’écran de connexion sans mot de passe pour le courriel
![]() |
Ci-dessous se trouve un exemple complet de l’écran.
import { ChangeEvent } from "react";
import { LoginPasswordlessEmailCode as ScreenProvider } from "@auth0/auth0-acul-js";
// UI Components
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { Text } from "@/components/ui/text";
import { Link } from "@/components/ui/link";
import { Input } from "@/components/ui/input";
import { REGEXP_ONLY_DIGITS_AND_CHARS } from "input-otp"
import {
InputOTP,
InputOTPGroup,
InputOTPSlot,
} from "@/components/ui/input-otp"
import {
CardHeader,
CardTitle,
CardDescription,
CardContent,
} from "@/components/ui/card";
export default function LoginPasswordlessEmailCode() {
// Initialize the SDK for this screen
const screenProvider = new ScreenProvider();
// Handle the submit action
const formSubmitHandler = (event: ChangeEvent<HTMLFormElement>) => {
event.preventDefault();
// grab the value from the form
const OtpInput = event.target.querySelector(
"input#otp_code"
) as HTMLInputElement;
const identifierInput = event.target.querySelector(
"input#identifier"
) as HTMLInputElement;
// Call the SDK
screenProvider.submitCode({
username: identifierInput?.value,
code: OtpInput?.value
});
};
// Render the form
return (
<form noValidate onSubmit={formSubmitHandler}>
<CardHeader>
<CardTitle className="mb-2 text-3xl font-medium text-center">
{screenProvider.screen.texts?.title ?? "Verify yourself"}
</CardTitle>
<CardDescription className="mb-8 text-center">
{screenProvider.screen.texts?.description ??
"Enter the code sent to the email below"}
</CardDescription>
</CardHeader>
<CardContent>
<Text className="mb-4 text-large">
<span className="inline-block">
Continue as
<span className="inline-block ml-1 font-bold">
{screenProvider.screen.data?.username}.
</span>
</span>
<Link
href={screenProvider.screen.links.editIdentifierLink ?? "#"}
className="ml-2"
>
{screenProvider.screen.texts?.editText ?? "Edit Email"}
</Link>
</Text>
<Input
type="hidden"
name="identifier"
id="identifier"
value={screenProvider.screen.data?.username}
/>
<Label htmlFor="otp_code">
{screenProvider.screen.texts?.placeholder ?? "Enter the OTP Code"}
</Label>
<div className="flex items-center w-full space-y-2">
<InputOTP
maxLength={6}
pattern={REGEXP_ONLY_DIGITS_AND_CHARS}
id="otp_code"
name="otp_code"
>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>
<Button type="submit" className="ml-2">
{screenProvider.screen.texts?.buttonText ?? "Verify"}
</Button>
</div>
<Text>
{screenProvider.screen.texts?.resendText ?? "Didn't get the OTP?"}
<Link className="ml-1" href="#" onClick={screenProvider.resendCode}>
{screenProvider.screen.texts?.resendActionText ?? "Send again."}
</Link>
</Text>
</CardContent>
</form>
);
}
Was this helpful?
Importer et initialiser la trousse SDK
Dans le dossier auth0-acul-react-boilerplate/src
créez un dossier appelé screens
et un fichier appelé Login.tsx
. Importez la trousse SDK et, dans le composant React, initialisez la trousse SDK pour l’écran.
import { LoginPasswordlessEmailCode as ScreenProvider } from "@auth0/auth0-acul-js";
export default function LoginPasswordlessEmailCode() {
// Initialize the SDK for this screen
const screenProvider = new ScreenProvider();
...
}
Was this helpful?
Utilisez la trousse SDK pour accéder aux propriétés et méthodes de l’écran.
En utilisant la trousse SDK, vous pouvez accéder aux propriétés et aux méthodes de l’écran. La trousse SDK Auth0 ACUL JS fournit des propriétés et des méthodes pour accéder aux données.
Pour plus d’informations sur les données contextuelles, lisez Données contextuelle de connexion universelle.
<form noValidate onSubmit={formSubmitHandler}>
...
<CardContent>
<Text className="mb-4 text-large">
<span className="inline-block">
Continue as
<span className="inline-block ml-1 font-bold">
{screenProvider.screen.data?.username}.
</span>
</span>
<Link
href={screenProvider.screen.links.editIdentifierLink ?? "#"}
className="ml-2"
>
{screenProvider.screen.texts?.editText ?? "Edit Email"}
</Link>
</Text>
<Input
type="hidden"
name="identifier"
id="identifier"
value={screenProvider.screen.data?.username}
/>
<Label htmlFor="otp_code">
{screenProvider.screen.texts?.placeholder ?? "Enter the OTP Code"}
</Label>
<div className="flex items-center w-full space-y-2">
<InputOTP
maxLength={6}
pattern={REGEXP_ONLY_DIGITS_AND_CHARS}
id="otp_code"
name="otp_code"
>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>
<Button type="submit" className="ml-2">
{screenProvider.screen.texts?.buttonText ?? "Verify"}
</Button>
</div>
...
</CardContent>
</form>
);
}
Was this helpful?
Appeler l’action de soumission.
En utilisant le SDK, soumettez les données capturées à l’écran au serveur. Le serveur traite ces données et dirigera l’utilisateur vers l’étape suivante du flux. En cas d’erreurs, cet écran est rechargé, ce qui vous permet de les présenter à l’utilisateur. Les erreurs sont accessibles via la trousse SDK.
const formSubmitHandler = (event: ChangeEvent<HTMLFormElement>) => {
event.preventDefault();
// grab the value from the form
const OtpInput = event.target.querySelector(
"input#otp_code"
) as HTMLInputElement;
const identifierInput = event.target.querySelector(
"input#identifier"
) as HTMLInputElement;
// Call the SDK
screenProvider.submitCode({
username: identifierInput?.value,
code: OtpInput?.value
});
Was this helpful?
Option 2 : Créez l’écran de connexion sans mot de passe pour les SMS
![]() |
Ci-dessous se trouve un exemple complet de l’écran.
import { ChangeEvent } from "react";
import { LoginPasswordlessSmsOtp as ScreenProvider } from "@auth0/auth0-acul-js";
// UI Components
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { Text } from "@/components/ui/text";
import { Link } from "@/components/ui/link";
import { Input } from "@/components/ui/input";
import { REGEXP_ONLY_DIGITS_AND_CHARS } from "input-otp"
import {
InputOTP,
InputOTPGroup,
InputOTPSlot,
} from "@/components/ui/input-otp"
import {
CardHeader,
CardTitle,
CardDescription,
CardContent,
} from "@/components/ui/card";
export default function LoginPasswordlessSmsOtp() {
// Initialize the SDK for this screen
const screenProvider = new ScreenProvider();
// Handle the submit action
const formSubmitHandler = (event: ChangeEvent<HTMLFormElement>) => {
event.preventDefault();
// grab the value from the form
const OtpInput = event.target.querySelector(
"input#otp_code"
) as HTMLInputElement;
const identifierInput = event.target.querySelector(
"input#identifier"
) as HTMLInputElement;
// Call the SDK
screenProvider.submitOTP({
username: identifierInput?.value,
code: OtpInput?.value
});
};
// Render the form
return (
<form noValidate onSubmit={formSubmitHandler}>
<CardHeader>
<CardTitle className="mb-2 text-3xl font-medium text-center">
{screenProvider.screen.texts?.title ?? "Verify yourself"}
</CardTitle>
<CardDescription className="mb-8 text-center">
{screenProvider.screen.texts?.description ??
"Enter the code sent to the phone below"}
</CardDescription>
</CardHeader>
<CardContent>
<Text className="mb-4 text-large">
<span className="inline-block">
Continue as
<span className="inline-block ml-1 font-bold">
{screenProvider.screen.data?.username}.
</span>
</span>
<Link
href={screenProvider.screen.links?.edit_identifier ?? "#"}
className="ml-2"
>
{screenProvider.screen.texts?.editText ?? "Edit Phone"}
</Link>
</Text>
<Input
type="hidden"
name="identifier"
id="identifier"
value={screenProvider.screen.data?.username}
/>
<Label htmlFor="otp_code">
{screenProvider.screen.texts?.placeholder ?? "Enter the OTP Code"}
</Label>
<div className="flex items-center w-full space-y-2">
<InputOTP
maxLength={6}
pattern={REGEXP_ONLY_DIGITS_AND_CHARS}
id="otp_code"
name="otp_code"
>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>
<Button type="submit" className="ml-2">
{screenProvider.screen.texts?.buttonText ?? "Verify"}
</Button>
</div>
<Text>
{screenProvider.screen.texts?.resendText ?? "Didn't get the OTP?"}
<Link className="ml-1" href="#" onClick={screenProvider.resendOTP}>
{screenProvider.screen.texts?.resendActionText ?? "Send again."}
</Link>
</Text>
</CardContent>
</form>
);
}
Was this helpful?
Importer et initialiser la trousse SDK
Dans le dossier auth0-acul-react-boilerplate/src
créez un dossier appelé screens
et un fichier appelé Login.tsx
. Importez la trousse SDK et, dans le composant React, initialisez la trousse SDK pour l’écran.
import { LoginPasswordlessSmsOtp as ScreenProvider } from "@auth0/auth0-acul-js";
export default function LoginPasswordlessSmsOtp() {
// Initialize the SDK for this screen
const screenProvider = new ScreenProvider();
...
}
Was this helpful?
Utilisez la trousse SDK pour accéder aux propriétés et méthodes de l’écran.
En utilisant la trousse SDK, vous pouvez accéder aux propriétés et aux méthodes de l’écran. La trousse SDK Auth0 ACUL JS fournit des propriétés et des méthodes pour accéder aux données.
Pour plus d’informations sur les données contextuelles, lisez Données contextuelle de connexion universelle.
<form noValidate onSubmit={formSubmitHandler}>
...
<CardContent>
<Text className="mb-4 text-large">
<span className="inline-block">
Continue as
<span className="inline-block ml-1 font-bold">
{screenProvider.screen.data?.username}.
</span>
</span>
<Link
href={screenProvider.screen.links?.edit_identifier ?? "#"}
className="ml-2"
>
{screenProvider.screen.texts?.editText ?? "Edit Phone"}
</Link>
</Text>
<Input
type="hidden"
name="identifier"
id="identifier"
value={screenProvider.screen.data?.username}
/>
<Label htmlFor="otp_code">
{screenProvider.screen.texts?.placeholder ?? "Enter the OTP Code"}
</Label>
<div className="flex items-center w-full space-y-2">
<InputOTP
maxLength={6}
pattern={REGEXP_ONLY_DIGITS_AND_CHARS}
id="otp_code"
name="otp_code"
>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>
<Button type="submit" className="ml-2">
{screenProvider.screen.texts?.buttonText ?? "Verify"}
</Button>
</div>
...
</CardContent>
</form>
);
}
Was this helpful?
Appeler l’action de soumission.
En utilisant le SDK, soumettez les données capturées à l’écran au serveur. Le serveur traite ces données et dirigera l’utilisateur vers l’étape suivante du flux. En cas d’erreurs, cet écran est rechargé, ce qui vous permet de les présenter à l’utilisateur. Les erreurs sont accessibles via la trousse SDK.
const formSubmitHandler = (event: ChangeEvent<HTMLFormElement>) => {
event.preventDefault();
// grab the value from the form
const OtpInput = event.target.querySelector(
"input#otp_code"
) as HTMLInputElement;
const identifierInput = event.target.querySelector(
"input#identifier"
) as HTMLInputElement;
// Call the SDK
screenProvider.submitCode({
username: identifierInput?.value,
code: OtpInput?.value
});
Was this helpful?
3 : Configurez ACUL pour utiliser des ressources locales.
Utilisez l’interface de ligne de commande Auth0, Terraform ou Management API pour activer ACUL. Pour des détails sur ce qui peut être configuré, consultez Configurer les écrans ACUL.
Dans le répertoire racine de votre projet, créez un dossier settings
et incluez-y un fichier {SCREENNAME}.json
.
//settings.json
{
"rendering_mode": "advanced",
"context_configuration": [
"screen.texts"
],
"head_tags": [
{
"attributes": {
"async": true,
"defer": true,
"integrity": [
"ASSET_SHA"
],
"src": "http://127.0.0.1:8080/index.js"
},
"tag": "script"
},
{
"attributes": {
"href": "http://127.0.0.1:8080/index.css",
"rel": "stylesheet"
},
"tag": "link"
}
]
}
Was this helpful?
auth0 ul customize --rendering-mode advanced --prompt {SCREENNAME} --screen {SCREENNAME} --settings-file ./settings/{SCREENNAME}.json
Was this helpful?
Dans le répertoire racine de votre projet, créez un fichier login-id.json
:
//login-id.json
{
"rendering_mode": "advanced",
"context_configuration": [
"screen.texts"
],
"head_tags": [
{
"attributes": {
"async": true,
"defer": true,
"integrity": [
"ASSET_SHA"
],
"src": "http://127.0.0.1:8080/index.js"
},
"tag": "script"
},
{
"attributes": {
"href": "http://127.0.0.1:8080/index.css",
"rel": "stylesheet"
},
"tag": "link"
}
]
}
Was this helpful?
Activer ACUL avec Auth0 Terraform
prompts:
identifier_first: true
universal_login_experience: classic
mfa-login-options:
pageTitle: 'Log in to ${clientName}'
authenticatorNamesSMS: 'SMS'
screenRenderers:
- login-id:
login-id: ./prompts/screenRenderSettings/login-id.json
Was this helpful?
Vous pouvez utiliser Auth0 Management API pour activer ACUL.
curl --location --request PATCH 'https://{YOUR-CUSTOM-DOMAIN}/api/v2/prompts/{YOUR-PROMPT}/screen/{YOUR-SCREEN}/rendering' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <API TOKEN>' \
--data '{
"rendering_mode": "advanced",
"context_configuration": [
"branding.settings",
"organization.branding",
"screen.texts",
"tenant.name",
"tenant.friendly_name",
"tenant.enabled_locales",
"untrusted_data.submitted_form_data",
"untrusted_data.authorization_params.ui_locales",
"untrusted_data.authorization_params.login_hint",
"untrusted_data.authorization_params.screen_hint"
],
"head_tags": [
{
"tag": "script",
"attributes": {
"src": "http://127.0.0.1:8080/index.js",
"defer": true
}
},
{
"tag": "link",
"attributes": {
"rel": "stylesheet",
"href": "http://127.0.0.1:8080/index.css"
}
},
{
"tag": "meta",
"attributes": {
"name": "viewport",
"content": "width=device-width, initial-scale=1"
}
}
]
}'
Was this helpful?
Testez votre configuration sur un serveur local.
ACUL exige que les ressources soient hébergées sur une URL publique. Démarrez un serveur local et testez vos ressources avant de les déployer.
// Creates the local assets
npm run build
cd dist
// Serves the assets from localhost
npx serve -p 8080 --cors
Was this helpful?
4 : Déployez les ressources et mettez à jour la configuration de votre locataire.
La personnalisation avancée pour la connexion universelle fonctionne avec tous les programmes de regroupement JavaScript modernes, comme Vite et Webpack. Pour plus d’informations, lisez Déployer des personnalisations avancées en production.
Pour plus d’informations sur le déploiement d’ACUL pour votre locataire, lisez Configurer les écrans ACUL.
Contenu relatif
Pour plus d’informations sur les écrans qui peuvent être personnalisés, lisez Personnalisations avancées pour la connexion universelle : écrans.