> ## Documentation Index
> Fetch the complete documentation index at: https://translations.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Décrit comment créer vos propres flux MFA à l’aide des SMS ou des appels vocaux comme facteurs d’authentification.

# Inscrire et vérifier les authentificateurs par courriel

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
              processedNode = processedNode.replaceAll(new RegExp(escapedKey, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****MASKED*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

Auth0 offre un flux intégré d’inscription à la <Tooltip tip="Authentification multifacteur (MFA) : processus d’authentification de l’utilisateur qui utilise un facteur en plus du nom d’utilisateur et du mot de passe, comme un code envoyé par SMS." cta="Voir le glossaire" href="/fr-CA/docs/glossary?term=MFA">MFA</Tooltip> et d’authentification avec [Universal Login](/fr-CA/docs/authenticate/login/auth0-universal-login). Toutefois, si vous souhaitez créer votre propre interface utilisateur, vous pouvez utiliser l’[API MFA](/fr-CA/docs/secure/multi-factor-authentication/multi-factor-authentication-developer-resources/mfa-api) pour y parvenir.

Lorsque le courriel est activé comme facteur, tous les utilisateurs dont le courriel est vérifié pourront l’utiliser pour effectuer la MFA.

<Card title="La disponibilité varie selon le forfait Auth0">
  La disponibilité de cette fonctionnalité dépend à la fois de votre implémentation de connexion et de votre forfait Auth0 ou de votre entente personnalisée. Pour en savoir plus, consultez [Tarification](https://auth0.com/pricing).
</Card>

<div id="prerequisites">
  ## Prérequis
</div>

Avant de pouvoir utiliser les API MFA, vous devez activer le type d’octroi MFA pour votre application. Accédez à [Auth0 Dashboard > Applications > Paramètres avancés > Types d’octroi](https://manage.auth0.com/#/applications) et sélectionnez **MFA**.

* [Configurer le courriel](/fr-CA/docs/secure/multi-factor-authentication/multi-factor-authentication-factors/configure-email-notifications-for-mfa) comme facteur dans l’Auth0 Dashboard ou à l’aide de la [Management API](https://auth0.com/docs/api/management/v2#!/Guardian/put_factors_by_name).

<div id="enroll-with-email">
  ## Inscription par courriel
</div>

Pour permettre aux utilisateurs d’inscrire d’autres adresses courriel en plus du courriel vérifié associé à leur identité principale, vous devez suivre les étapes ci-dessous.

<div id="get-mfa-token">
  ### Obtenir un jeton MFA
</div>

Selon le moment où vous déclenchez l’inscription, vous pouvez obtenir un <Tooltip tip="Jeton d’accès : justificatif d’autorisation, sous la forme d’une chaîne opaque ou d’un JWT, utilisé pour accéder à une API." cta="Voir le glossaire" href="/fr-CA/docs/glossary?term=access+token">jeton d’accès</Tooltip> pour utiliser l’API MFA de différentes façons :

* Si vous effectuez l’inscription pendant l’authentification, consultez [S’authentifier avec Resource Owner Password Grant et la MFA](/fr-CA/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa).
* Si vous souhaitez permettre à l’utilisateur d’inscrire un facteur à tout moment, consultez [Gérer les inscriptions aux facteurs MFA](/fr-CA/docs/secure/multi-factor-authentication/manage-mfa-auth0-apis/manage-authenticator-factors-mfa-api).

<div id="enroll-authenticator">
  ### Inscrire l’authentificateur
</div>

Faites une requête `POST` au point de terminaison MFA Associate pour inscrire l’authentificateur de l’utilisateur. Le jeton Bearer requis par ce point de terminaison est le jeton MFA obtenu à l’étape précédente.

Utilisez les paramètres suivants :

| Paramètre              | Valeur                                                    |
| ---------------------- | --------------------------------------------------------- |
| `authentication_types` | `[oob]`                                                   |
| `oob_channels`         | `[email]`                                                 |
| `email`                | `email@address.com`, l’adresse courriel de l’utilisateur. |

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://{yourDomain}/mfa/associate' \
    --header 'authorization: Bearer MFA_TOKEN' \
    --header 'content-type: application/json' \
    --data '{ "authenticator_types": ["oob"], "oob_channels": ["email"], "email" : "email@address.com" }'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/mfa/associate");
  var request = new RestRequest(Method.POST);
  request.AddHeader("authorization", "Bearer MFA_TOKEN");
  request.AddHeader("content-type", "application/json");
  request.AddParameter("application/json", "{ "authenticator_types": ["oob"], "oob_channels": ["email"], "email" : "email@address.com" }", ParameterType.RequestBody);
  IRestResponse response = client.Execute(request);
  ```

  ```go Go theme={null}
  package main

  import (
  	"fmt"
  	"strings"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://{yourDomain}/mfa/associate"

  	payload := strings.NewReader("{ "authenticator_types": ["oob"], "oob_channels": ["email"], "email" : "email@address.com" }")

  	req, _ := http.NewRequest("POST", url, payload)

  	req.Header.Add("authorization", "Bearer MFA_TOKEN")
  	req.Header.Add("content-type", "application/json")

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java theme={null}
  HttpResponse<String> response = Unirest.post("https://{yourDomain}/mfa/associate")
    .header("authorization", "Bearer MFA_TOKEN")
    .header("content-type", "application/json")
    .body("{ "authenticator_types": ["oob"], "oob_channels": ["email"], "email" : "email@address.com" }")
    .asString();
  ```

  ```javascript Node.JS theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'POST',
    url: 'https://{yourDomain}/mfa/associate',
    headers: {authorization: 'Bearer MFA_TOKEN', 'content-type': 'application/json'},
    data: {
      authenticator_types: ['oob'],
      oob_channels: ['email'],
      email: 'email@address.com'
    }
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```php PHP theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://{yourDomain}/mfa/associate",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => "{ "authenticator_types": ["oob"], "oob_channels": ["email"], "email" : "email@address.com" }",
    CURLOPT_HTTPHEADER => [
      "authorization: Bearer MFA_TOKEN",
      "content-type: application/json"
    ],
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python theme={null}
  import http.client

  conn = http.client.HTTPSConnection("")

  payload = "{ "authenticator_types": ["oob"], "oob_channels": ["email"], "email" : "email@address.com" }"

  headers = {
      'authorization': "Bearer MFA_TOKEN",
      'content-type': "application/json"
      }

  conn.request("POST", "/{yourDomain}/mfa/associate", payload, headers)

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://{yourDomain}/mfa/associate")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Post.new(url)
  request["authorization"] = 'Bearer MFA_TOKEN'
  request["content-type"] = 'application/json'
  request.body = "{ "authenticator_types": ["oob"], "oob_channels": ["email"], "email" : "email@address.com" }"

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

Si la requête réussit, vous recevez une réponse comme celle-ci :

```json lines theme={null}
{
    "authenticator_type": "oob",
    "binding_method": "prompt",
    "oob_code" : "Fe26..nWE",
    "oob_channel": "email",
    "recovery_codes": [ "N3BGPZZWJ85JLCNPZBDW6QXC" ]
  }
```

Si vous obtenez l’erreur `User is already enrolled`, c’est que l’utilisateur a déjà un facteur MFA inscrit. Avant d’associer un autre facteur à l’utilisateur, vous devez lui faire passer une vérification au moyen du facteur existant.

S’il s’agit de la première fois que l’utilisateur associe un authentificateur, vous remarquerez que la réponse inclut `recovery_codes`. Les codes de récupération servent à accéder au compte de l’utilisateur s’il perd l’accès au compte ou à l’appareil utilisé pour son authentification à deux facteurs. Ces codes sont à usage unique, et de nouveaux codes sont générés au besoin.

<div id="confirm-email-enrollment">
  ### Confirmer l’inscription par courriel
</div>

L’utilisateur devrait recevoir un courriel contenant le code à six chiffres qu’il pourra fournir à l’application.

Pour terminer l’inscription, effectuez une requête `POST` vers le point de terminaison [**`/oath/token`**](https://auth0.com/docs/api/authentication#get-token). Incluez le `oob_code` renvoyé dans la réponse précédente ainsi que le `binding_code` avec la valeur figurant dans le courriel.

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://{yourDomain}/oauth/token' \
    --data grant_type=http://auth0.com/oauth/grant-type/mfa-oob \
    --data 'mfa_token={mfaToken}' \
    --data 'oob_code={oobCode}' \
    --data 'binding_code={userEmailOtpCode}' \
    --data 'client_id={yourClientId}' \
    --data 'client_secret={yourClientSecret}'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/oauth/token");
  var request = new RestRequest(Method.POST);
  request.AddParameter("undefined", "grant_type=http%3A%2F%2Fauth0.com%2Foauth%2Fgrant-type%2Fmfa-oob&mfa_token=%7BmfaToken%7D&oob_code=%7BoobCode%7D&binding_code=%7BuserEmailOtpCode%7D&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D", ParameterType.RequestBody);
  IRestResponse response = client.Execute(request);
  ```

  ```go Go theme={null}
  package main

  import (
  	"fmt"
  	"strings"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://{yourDomain}/oauth/token"

  	payload := strings.NewReader("grant_type=http%3A%2F%2Fauth0.com%2Foauth%2Fgrant-type%2Fmfa-oob&mfa_token=%7BmfaToken%7D&oob_code=%7BoobCode%7D&binding_code=%7BuserEmailOtpCode%7D&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D")

  	req, _ := http.NewRequest("POST", url, payload)

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java theme={null}
  HttpResponse<String> response = Unirest.post("https://{yourDomain}/oauth/token")
    .body("grant_type=http%3A%2F%2Fauth0.com%2Foauth%2Fgrant-type%2Fmfa-oob&mfa_token=%7BmfaToken%7D&oob_code=%7BoobCode%7D&binding_code=%7BuserEmailOtpCode%7D&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D")
    .asString();
  ```

  ```javascript Node.JS theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'POST',
    url: 'https://{yourDomain}/oauth/token',
    data: new URLSearchParams({
      grant_type: 'http://auth0.com/oauth/grant-type/mfa-oob',
      mfa_token: '{mfaToken}',
      oob_code: '{oobCode}',
      binding_code: '{userEmailOtpCode}',
      client_id: '{yourClientId}',
      client_secret: '{yourClientSecret}'
    })
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```php PHP theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://{yourDomain}/oauth/token",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => "grant_type=http%3A%2F%2Fauth0.com%2Foauth%2Fgrant-type%2Fmfa-oob&mfa_token=%7BmfaToken%7D&oob_code=%7BoobCode%7D&binding_code=%7BuserEmailOtpCode%7D&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D",
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python theme={null}
  import http.client

  conn = http.client.HTTPSConnection("")

  payload = "grant_type=http%3A%2F%2Fauth0.com%2Foauth%2Fgrant-type%2Fmfa-oob&mfa_token=%7BmfaToken%7D&oob_code=%7BoobCode%7D&binding_code=%7BuserEmailOtpCode%7D&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D"

  conn.request("POST", "/{yourDomain}/oauth/token", payload)

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://{yourDomain}/oauth/token")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Post.new(url)
  request.body = "grant_type=http%3A%2F%2Fauth0.com%2Foauth%2Fgrant-type%2Fmfa-oob&mfa_token=%7BmfaToken%7D&oob_code=%7BoobCode%7D&binding_code=%7BuserEmailOtpCode%7D&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D"

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

Si l’appel réussit, vous recevrez une réponse au format suivant contenant le jeton d’accès :

```json lines theme={null}
{
  "id_token": "eyJ...i",
  "access_token": "eyJ...i",
  "expires_in": 600,
  "scope": "openid profile",
  "token_type": "Bearer"
}
```

À ce stade, l’authentificateur est entièrement associé et prêt à être utilisé, et vous disposez des jetons d’authentification de l’utilisateur.

Vous pouvez à tout moment vérifier si un authentificateur a été confirmé en appelant le point de terminaison `MFA Authenticators`. Si l’authentificateur est confirmé, la valeur renvoyée pour `active` est `true`.

Au besoin, vous pouvez personnaliser les courriels que les utilisateurs reçoivent. Consultez [Personnaliser les modèles de courriel](/fr-CA/docs/customize/email/email-templates) pour en savoir plus.

<div id="challenge-with-email">
  ## Vérification par courriel
</div>

<div id="get-mfa-token">
  ### Obtenir un jeton MFA
</div>

Obtenez un jeton MFA en suivant les étapes décrites dans [Authentification avec Resource Owner Password Grant et MFA](/fr-CA/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa).

<div id="retrieve-enrolled-authenticators">
  ### Récupérer les authentificateurs inscrits
</div>

Pour demander une vérification à l’utilisateur, vous avez besoin du `authenticator_id` du facteur que vous souhaitez utiliser. Vous pouvez répertorier tous les authentificateurs inscrits à l’aide du point de terminaison MFA Authenticators :

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request GET \
    --url 'https://{yourDomain}/mfa/authenticators' \
    --header 'authorization: Bearer MFA_TOKEN' \
    --header 'content-type: application/json'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/mfa/authenticators");
  var request = new RestRequest(Method.GET);
  request.AddHeader("authorization", "Bearer MFA_TOKEN");
  request.AddHeader("content-type", "application/json");
  IRestResponse response = client.Execute(request);
  ```

  ```go Go theme={null}
  package main

  import (
  	"fmt"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://{yourDomain}/mfa/authenticators"

  	req, _ := http.NewRequest("GET", url, nil)

  	req.Header.Add("authorization", "Bearer MFA_TOKEN")
  	req.Header.Add("content-type", "application/json")

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java theme={null}
  HttpResponse<String> response = Unirest.get("https://{yourDomain}/mfa/authenticators")
    .header("authorization", "Bearer MFA_TOKEN")
    .header("content-type", "application/json")
    .asString();
  ```

  ```javascript Node.JS theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'GET',
    url: 'https://{yourDomain}/mfa/authenticators',
    headers: {authorization: 'Bearer MFA_TOKEN', 'content-type': 'application/json'}
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```php PHP theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://{yourDomain}/mfa/authenticators",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HTTPHEADER => [
      "authorization: Bearer MFA_TOKEN",
      "content-type: application/json"
    ],
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python theme={null}
  import http.client

  conn = http.client.HTTPSConnection("")

  headers = {
      'authorization': "Bearer MFA_TOKEN",
      'content-type': "application/json"
      }

  conn.request("GET", "/{yourDomain}/mfa/authenticators", headers=headers)

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://{yourDomain}/mfa/authenticators")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Get.new(url)
  request["authorization"] = 'Bearer MFA_TOKEN'
  request["content-type"] = 'application/json'

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

<div id="challenge-user-with-otp">
  ### Soumettre l’utilisateur à une vérification OTP
</div>

Pour déclencher une vérification par courriel, envoyez une requête `POST` au point de terminaison MFA Challenge en utilisant l’`authenticator_id` correspondant et le `mfa_token`.

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://{yourDomain}/mfa/challenge' \
    --data '{  "client_id": "{yourClientId}",  "client_secret": "{yourClientSecret}",  "challenge_type": "oob",  "authenticator_id": "email|dev_NU1Ofuw3Cw0XCt5x", "mfa_token": "{mfaToken}" }'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/mfa/challenge");
  var request = new RestRequest(Method.POST);
  request.AddParameter("undefined", "{  "client_id": "{yourClientId}",  "client_secret": "{yourClientSecret}",  "challenge_type": "oob",  "authenticator_id": "email|dev_NU1Ofuw3Cw0XCt5x", "mfa_token": "{mfaToken}" }", ParameterType.RequestBody);
  IRestResponse response = client.Execute(request);
  ```

  ```go Go theme={null}
  package main

  import (
  	"fmt"
  	"strings"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://{yourDomain}/mfa/challenge"

  	payload := strings.NewReader("{  "client_id": "{yourClientId}",  "client_secret": "{yourClientSecret}",  "challenge_type": "oob",  "authenticator_id": "email|dev_NU1Ofuw3Cw0XCt5x", "mfa_token": "{mfaToken}" }")

  	req, _ := http.NewRequest("POST", url, payload)

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java theme={null}
  HttpResponse<String> response = Unirest.post("https://{yourDomain}/mfa/challenge")
    .body("{  "client_id": "{yourClientId}",  "client_secret": "{yourClientSecret}",  "challenge_type": "oob",  "authenticator_id": "email|dev_NU1Ofuw3Cw0XCt5x", "mfa_token": "{mfaToken}" }")
    .asString();
  ```

  ```javascript Node.JS theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'POST',
    url: 'https://{yourDomain}/mfa/challenge',
    data: {
      client_id: '{yourClientId}',
      client_secret: '{yourClientSecret}',
      challenge_type: 'oob',
      authenticator_id: 'email|dev_NU1Ofuw3Cw0XCt5x',
      mfa_token: '{mfaToken}'
    }
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```php PHP theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://{yourDomain}/mfa/challenge",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => "{  "client_id": "{yourClientId}",  "client_secret": "{yourClientSecret}",  "challenge_type": "oob",  "authenticator_id": "email|dev_NU1Ofuw3Cw0XCt5x", "mfa_token": "{mfaToken}" }",
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python theme={null}
  import http.client

  conn = http.client.HTTPSConnection("")

  payload = "{  "client_id": "{yourClientId}",  "client_secret": "{yourClientSecret}",  "challenge_type": "oob",  "authenticator_id": "email|dev_NU1Ofuw3Cw0XCt5x", "mfa_token": "{mfaToken}" }"

  conn.request("POST", "/{yourDomain}/mfa/challenge", payload)

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://{yourDomain}/mfa/challenge")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Post.new(url)
  request.body = "{  "client_id": "{yourClientId}",  "client_secret": "{yourClientSecret}",  "challenge_type": "oob",  "authenticator_id": "email|dev_NU1Ofuw3Cw0XCt5x", "mfa_token": "{mfaToken}" }"

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

<div id="complete-authentication-using-received-code">
  ### Terminez l’authentification avec le code reçu
</div>

Si l’opération réussit, vous recevez la réponse suivante :

```json lines theme={null}
{
  "challenge_type": "oob",
  "oob_code": "abcd1234...",
  "binding_method": "prompt"
}
```

Votre application doit inviter l’utilisateur à saisir le code et l’envoyer dans la requête, dans le paramètre `binding_code`, lors de l’appel suivant au point de terminaison `oauth``/token` :

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://{yourDomain}/oauth/token' \
    --header 'content-type: application/x-www-form-urlencoded' \
    --data grant_type=http://auth0.com/oauth/grant-type/mfa-oob \
    --data 'client_id={yourClientId}' \
    --data 'client_secret={yourClientSecret}' \
    --data 'mfa_token={mfaToken}' \
    --data 'oob_code={oobCode}' \
    --data 'binding_code={userEmailOtpCode}'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/oauth/token");
  var request = new RestRequest(Method.POST);
  request.AddHeader("content-type", "application/x-www-form-urlencoded");
  request.AddParameter("application/x-www-form-urlencoded", "grant_type=http%3A%2F%2Fauth0.com%2Foauth%2Fgrant-type%2Fmfa-oob&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&mfa_token=%7BmfaToken%7D&oob_code=%7BoobCode%7D&binding_code=%7BuserEmailOtpCode%7D", ParameterType.RequestBody);
  IRestResponse response = client.Execute(request);
  ```

  ```go Go theme={null}
  package main

  import (
  	"fmt"
  	"strings"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://{yourDomain}/oauth/token"

  	payload := strings.NewReader("grant_type=http%3A%2F%2Fauth0.com%2Foauth%2Fgrant-type%2Fmfa-oob&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&mfa_token=%7BmfaToken%7D&oob_code=%7BoobCode%7D&binding_code=%7BuserEmailOtpCode%7D")

  	req, _ := http.NewRequest("POST", url, payload)

  	req.Header.Add("content-type", "application/x-www-form-urlencoded")

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java theme={null}
  HttpResponse<String> response = Unirest.post("https://{yourDomain}/oauth/token")
    .header("content-type", "application/x-www-form-urlencoded")
    .body("grant_type=http%3A%2F%2Fauth0.com%2Foauth%2Fgrant-type%2Fmfa-oob&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&mfa_token=%7BmfaToken%7D&oob_code=%7BoobCode%7D&binding_code=%7BuserEmailOtpCode%7D")
    .asString();
  ```

  ```javascript Node.JS theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'POST',
    url: 'https://{yourDomain}/oauth/token',
    headers: {'content-type': 'application/x-www-form-urlencoded'},
    data: new URLSearchParams({
      grant_type: 'http://auth0.com/oauth/grant-type/mfa-oob',
      client_id: '{yourClientId}',
      client_secret: '{yourClientSecret}',
      mfa_token: '{mfaToken}',
      oob_code: '{oobCode}',
      binding_code: '{userEmailOtpCode}'
    })
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```php PHP theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://{yourDomain}/oauth/token",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => "grant_type=http%3A%2F%2Fauth0.com%2Foauth%2Fgrant-type%2Fmfa-oob&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&mfa_token=%7BmfaToken%7D&oob_code=%7BoobCode%7D&binding_code=%7BuserEmailOtpCode%7D",
    CURLOPT_HTTPHEADER => [
      "content-type: application/x-www-form-urlencoded"
    ],
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python theme={null}
  import http.client

  conn = http.client.HTTPSConnection("")

  payload = "grant_type=http%3A%2F%2Fauth0.com%2Foauth%2Fgrant-type%2Fmfa-oob&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&mfa_token=%7BmfaToken%7D&oob_code=%7BoobCode%7D&binding_code=%7BuserEmailOtpCode%7D"

  headers = { 'content-type': "application/x-www-form-urlencoded" }

  conn.request("POST", "/{yourDomain}/oauth/token", payload, headers)

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://{yourDomain}/oauth/token")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Post.new(url)
  request["content-type"] = 'application/x-www-form-urlencoded'
  request.body = "grant_type=http%3A%2F%2Fauth0.com%2Foauth%2Fgrant-type%2Fmfa-oob&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&mfa_token=%7BmfaToken%7D&oob_code=%7BoobCode%7D&binding_code=%7BuserEmailOtpCode%7D"

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

Si l’appel réussit, vous recevrez une réponse au format ci-dessous contenant le jeton d’accès :

```json lines theme={null}
{
  "id_token": "eyJ...i",
  "access_token": "eyJ...i",
  "expires_in": 600,
  "scope": "openid profile",
  "token_type": "Bearer"
}
```

<div id="customize-mfa">
  ## Personnaliser la MFA
</div>

<Warning>
  La MFA personnalisable avec les flux Resource Owner Password Grant, Embedded ou Jeton d’actualisation est en accès anticipé. En utilisant cette fonctionnalité, vous acceptez les conditions d’essai gratuit applicables de la [Master Subscription Agreement](https://www.okta.com/legal/) d’Okta. Pour en savoir plus sur les phases de lancement d’Auth0, consultez [Phases de lancement des produits](/fr-CA/docs/troubleshoot/product-lifecycle/product-release-stages). Pour participer à l’accès anticipé, communiquez avec [Auth0 Support](https://support.auth0.com/).
</Warning>

La MFA personnalisable permet aux utilisateurs de s’inscrire et de répondre aux vérifications avec les facteurs de leur choix pris en charge par votre application.

Lors de l’authentification au point de terminaison `oauth/token`, la réponse renvoie l’erreur `mfa_required`, qui inclut le `mfa_token` à utiliser avec l’API MFA, ainsi que le paramètre `mfa_requirements` contenant une liste d’authentificateurs :

```json theme={null}
{
  "error": "mfa_required",
  "error_description": "Multifactor authentication required",
  "mfa_token": "Fe26...Ha",
  "mfa_requirements": {
    "challenge": [
      { "type": "otp" },
      { "type": "push-notification" },
      { "type": "phone" },
      { "type": "recovery-code" }
      { "type": "email"} //fonctionne uniquement avec challenge
    ]
  }
}
```

Utilisez le `mfa_token` pour appeler le point de terminaison [`mfa/authenticator`](/fr-CA/docs/api/authentication/muti-factor-authentication/list-authenticators) afin d’obtenir la liste de tous les facteurs que l’utilisateur a inscrits et de trouver le type pris en charge par votre application.  Vous devez également obtenir la valeur `authenticator_type` correspondante pour lancer les vérifications :

```json theme={null}
[
  {
    "type": "recovery-code",
    "id": "recovery-code|dev_qpOkGUOxBpw6R16t",
    "authenticator_type": "recovery-code",
    "active": true
  },
  {
    "type": "otp",
    "id": "totp|dev_6NWz8awwC8brh2dN",
    "authenticator_type": "otp",
    "active": true
  }
]
```

Forcez la vérification MFA en appelant le point de terminaison [`request/mfa/challenge`](/fr-CA/docs/api/authentication/muti-factor-authentication/request-mfa-challenge).

Personnalisez davantage votre flux MFA avec les Actions d’Auth0. Pour en savoir plus, consultez [Actions Triggers: post-challenge - API Object](/fr-CA/docs/customize/actions/explore-triggers/password-reset-triggers/post-challenge-trigger/post-challenge-api-object).

<div id="learn-more">
  ## En savoir plus
</div>

* [Gérer les facteurs d’authentification avec l’API d’authentification](/fr-CA/docs/secure/multi-factor-authentication/manage-mfa-auth0-apis/manage-authenticator-factors-mfa-api)
* [Vérification à l’aide de codes de récupération](/fr-CA/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/challenge-with-recovery-codes)
* [Inscrire des authentificateurs OTP et effectuer une vérification](/fr-CA/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-and-challenge-otp-authenticators)
* [Inscrire des authentificateurs Push et effectuer une vérification](/fr-CA/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-and-challenge-push-authenticators)
* [Inscrire des authentificateurs SMS et vocaux et effectuer une vérification](/fr-CA/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-challenge-sms-voice-authenticators)
