> ## 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 en utilisant les SMS ou l’appel vocal comme facteur d’authentification.

# Inscrire et vérifier les authentificateurs SMS et d’appel vocal

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) + "*****MASQUÉ*****";
          }
          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 <Tooltip tip="Authentification multifacteur (MFA) : processus d’authentification de l’utilisateur qui utilise un facteur en plus du nom d’utilisateur et mot de passe, comme un code envoyé par SMS." cta="Voir le glossaire" href="/docs/fr-ca/glossary?term=MFA">MFA</Tooltip> intégré d’inscription et d’authentification à l’aide de [Universal Login](/docs/fr-ca/authenticate/login/auth0-universal-login). Cependant, si vous souhaitez créer votre propre interface utilisateur, vous pouvez utiliser la [MFA API](/docs/fr-ca/secure/multi-factor-authentication/multi-factor-authentication-developer-resources/mfa-api) pour le faire.

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

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

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

<div id="enroll-with-sms-or-voice">
  ## S’inscrire par SMS ou appel vocal
</div>

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

Selon le moment où vous lancez 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="/docs/fr-ca/glossary?term=access+token">jeton d’accès</Tooltip> pour utiliser la MFA API de différentes façons :

* Si vous effectuez l’inscription pendant l’authentification, consultez [S’authentifier avec Resource Owner Password Grant et MFA](/docs/fr-ca/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](/docs/fr-ca/secure/multi-factor-authentication/manage-mfa-auth0-apis/manage-authenticator-factors-mfa-api).

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

Faites une requête `POST` à l’endpoint MFA Associate pour inscrire l’authentificateur de l’utilisateur. Le bearer token exigé par cet endpoint est le MFA token obtenu à l’étape précédente.

Pour l’inscription par SMS ou appel vocal, l’utilisateur s’inscrit avec un numéro de téléphone qui peut être utilisé pour une demande de vérification par SMS ou par appel vocal. Indiquez les paramètres ci-dessous pour faire une requête à l’endpoint. Le paramètre `oob_channels` indique comment vous voulez envoyer le code à l’utilisateur (SMS ou appel vocal).

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://{yourDomain}/mfa/associate' \
    --header 'authorization: Bearer {mfaToken}' \
    --header 'content-type: application/json' \
    --data '{ "authenticator_types": ["oob"], "oob_channels": ["sms"], "phone_number": "+11...9" }'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/mfa/associate");
  var request = new RestRequest(Method.POST);
  request.AddHeader("authorization", "Bearer {mfaToken}");
  request.AddHeader("content-type", "application/json");
  request.AddParameter("application/json", "{ "authenticator_types": ["oob"], "oob_channels": ["sms"], "phone_number": "+11...9" }", 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": ["sms"], "phone_number": "+11...9" }")

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

  	req.Header.Add("authorization", "Bearer {mfaToken}")
  	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 {mfaToken}")
    .header("content-type", "application/json")
    .body("{ "authenticator_types": ["oob"], "oob_channels": ["sms"], "phone_number": "+11...9" }")
    .asString();
  ```

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

  var options = {
    method: 'POST',
    url: 'https://{yourDomain}/mfa/associate',
    headers: {authorization: 'Bearer {mfaToken}', 'content-type': 'application/json'},
    data: {authenticator_types: ['oob'], oob_channels: ['sms'], phone_number: '+11...9'}
  };

  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": ["sms"], "phone_number": "+11...9" }",
    CURLOPT_HTTPHEADER => [
      "authorization: Bearer {mfaToken}",
      "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": ["sms"], "phone_number": "+11...9" }"

  headers = {
      'authorization': "Bearer {mfaToken}",
      '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_PEER

  request = Net::HTTP::Post.new(url)
  request["authorization"] = 'Bearer {mfaToken}'
  request["content-type"] = 'application/json'
  request.body = "{ "authenticator_types": ["oob"], "oob_channels": ["sms"], "phone_number": "+11...9" }"

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

| Paramètre              | Valeur                                                                                   |
| ---------------------- | ---------------------------------------------------------------------------------------- |
| `authentication_types` | `[oob]`                                                                                  |
| `oob_channels`         | `[sms]` ou `[voice]`                                                                     |
| `phone_number`         | `+11...9`, le numéro de téléphone au [format E.164](https://en.wikipedia.org/wiki/e.164) |

Si l’opération réussit, vous recevez une réponse comme celle-ci :

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

Si vous obtenez l’erreur `User is already enrolled`, c’est que l’utilisateur a déjà un facteur MFA configuré. Avant d’associer un autre facteur à l’utilisateur, vous devez d’abord le soumettre à une vérification à l’aide du facteur existant.

S’il s’agit de la première fois que l’utilisateur associe un authentificateur, vous remarquerez que la réponse comprend `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 deuxième facteur d’authentification. Ces codes sont à usage unique, et de nouveaux codes sont générés au besoin.

<div id="confirm-sms-or-voice-enrollment">
  ### Confirmer l’inscription par SMS ou appel vocal
</div>

Les utilisateurs devraient recevoir un message contenant un code à 6 chiffres qu’ils devront fournir à l’application.

Pour terminer l’inscription, envoyez une requête `POST` au <Tooltip tip="Point de terminaison de jeton : point de terminaison du serveur d’autorisation utilisé pour demander des jetons par programmation." cta="Voir le glossaire" href="/docs/fr-ca/glossary?term=OAuth">OAuth</Tooltip> <Tooltip tip="OAuth 2.0 : cadre d’autorisation qui définit les protocoles et les flux d’autorisation." cta="Voir le glossaire" href="/docs/fr-ca/glossary?term=Token+endpoint">point de terminaison de jeton</Tooltip>. Vous devez inclure le `oob_code` renvoyé dans la réponse précédente, ainsi que le `binding_code` avec la valeur reçue dans le message.

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://{yourDomain}/oauth/token' \
    --header 'authorization: Bearer {mfaToken}' \
    --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={userOtpCode}'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/oauth/token");
  var request = new RestRequest(Method.POST);
  request.AddHeader("authorization", "Bearer {mfaToken}");
  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=%7BuserOtpCode%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=%7BuserOtpCode%7D")

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

  	req.Header.Add("authorization", "Bearer {mfaToken}")
  	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("authorization", "Bearer {mfaToken}")
    .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=%7BuserOtpCode%7D")
    .asString();
  ```

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

  var options = {
    method: 'POST',
    url: 'https://{yourDomain}/oauth/token',
    headers: {
      authorization: 'Bearer {mfaToken}',
      '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: '{userOtpCode}'
    })
  };

  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=%7BuserOtpCode%7D",
    CURLOPT_HTTPHEADER => [
      "authorization: Bearer {mfaToken}",
      "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=%7BuserOtpCode%7D"

  headers = {
      'authorization': "Bearer {mfaToken}",
      '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_PEER

  request = Net::HTTP::Post.new(url)
  request["authorization"] = 'Bearer {mfaToken}'
  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=%7BuserOtpCode%7D"

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

Si la requête a réussi, 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"
}
```

<div id="challenge-with-sms-or-voice">
  ## Vérification par SMS ou appel vocal
</div>

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

Obtenez un jeton MFA en suivant la procédure décrite dans [S’authentifier avec Resource Owner Password Grant et MFA](/docs/fr-ca/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa).

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

Pour lancer une demande de vérification à l’utilisateur, vous avez besoin de l’`authenticator_id` du facteur que vous voulez interroger. Vous pouvez afficher 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_PEER

  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>

Vous obtiendrez une liste d’authentificateurs au format suivant :

```json lines theme={null}
[
    {
        "id": "recovery-code|dev_O4KYL4FtcLAVRsCl",
        "authenticator_type": "recovery-code",
        "active": true
    },
    {
        "id": "sms|dev_NU1Ofuw3Cw0XCt5x",
        "authenticator_type": "oob",
        "active": true,
        "oob_channel": "sms",
        "name": "XXXXXXXX8730"
    },
        {
        "id": "voice|dev_NU1Ofuw3Cw0XCt5x",
        "authenticator_type": "oob",
        "active": true,
        "oob_channel": "voice",
        "name": "XXXXXXXX8730"
    }
]
```

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

Pour déclencher une demande de vérification, envoyez une requête `POST` au point de terminaison MFA Challenge à l’aide de l’`authenticator_id` correspondant et du `mfa_token`.

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

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/mfa/challenge");
  var request = new RestRequest(Method.POST);
  request.AddHeader("content-type", "application/json");
  request.AddParameter("application/json", "{ "client_id": "{yourClientId}",  "client_secret": "{yourClientSecret}", "challenge_type": "oob", "authenticator_id": "sms|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": "sms|dev_NU1Ofuw3Cw0XCt5x", "mfa_token": "{mfaToken}" }")

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

  	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/challenge")
    .header("content-type", "application/json")
    .body("{ "client_id": "{yourClientId}",  "client_secret": "{yourClientSecret}", "challenge_type": "oob", "authenticator_id": "sms|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',
    headers: {'content-type': 'application/json'},
    data: {
      client_id: '{yourClientId}',
      client_secret: '{yourClientSecret}',
      challenge_type: 'oob',
      authenticator_id: 'sms|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": "sms|dev_NU1Ofuw3Cw0XCt5x", "mfa_token": "{mfaToken}" }",
    CURLOPT_HTTPHEADER => [
      "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 = "{ "client_id": "{yourClientId}",  "client_secret": "{yourClientSecret}", "challenge_type": "oob", "authenticator_id": "sms|dev_NU1Ofuw3Cw0XCt5x", "mfa_token": "{mfaToken}" }"

  headers = { 'content-type': "application/json" }

  conn.request("POST", "/{yourDomain}/mfa/challenge", 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/challenge")

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

  request = Net::HTTP::Post.new(url)
  request["content-type"] = 'application/json'
  request.body = "{ "client_id": "{yourClientId}",  "client_secret": "{yourClientSecret}", "challenge_type": "oob", "authenticator_id": "sms|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>

En cas de réussite, vous recevez la réponse suivante :

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

Votre application doit inviter l’utilisateur à saisir le code à 6 chiffres envoyé dans le message et définir ce code dans le paramètre `binding_code`. Vous pouvez vérifier le code et obtenir des jetons d’authentification à l’aide du point de terminaison de jeton d’OAuth0, en précisant les valeurs `binding_code` et `oob_code` renvoyées par la requête précédente :

<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=USER_OTP_CODE
  ```

  ```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=USER_OTP_CODE", 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=USER_OTP_CODE")

  	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=USER_OTP_CODE")
    .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: 'USER_OTP_CODE'
    })
  };

  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=USER_OTP_CODE",
    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=USER_OTP_CODE"

  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_PEER

  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=USER_OTP_CODE"

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

Si la requête a réussi, 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"
}
```

**Remarque :** les SMS et les erreurs « code invalide » sont soumis à une limitation du débit. Les codes SMS peuvent être envoyés 10 fois et la limite se rétablit à raison d’une fois par heure, tandis que l’erreur « code invalide » peut être renvoyée 10 fois et la limite se rétablit à raison d’une fois toutes les six minutes.

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

<Warning>
  La MFA personnalisable avec les flux Resource Owner Password Grant, Embedded ou Refresh Token est en Early Access. En utilisant cette fonctionnalité, vous acceptez les conditions applicables de l’essai gratuit énoncées dans le [Master Subscription Agreement](https://www.okta.com/legal/) d’Okta. Pour en savoir plus sur les étapes de lancement d’Auth0, consultez [Product Release Stages](/docs/fr-ca/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 d’inscrire les facteurs de leur choix pris en charge par votre application et de répondre aux demandes de vérification associées.

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 la MFA API, 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 envoyer une requête au point de terminaison [`mfa/authenticator`](/docs/fr-ca/api/authentication/muti-factor-authentication/list-authenticators) afin d’obtenir la liste de tous les facteurs auxquels l’utilisateur s’est inscrit et de repérer un type pris en charge par votre application.  Vous devez aussi obtenir l’`authenticator_type` correspondant pour lancer des demandes de vérification :

```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`](/docs/fr-ca/api/authentication/muti-factor-authentication/request-mfa-challenge).

Personnalisez davantage votre processus MFA avec Auth0 Actions. Pour en savoir plus, consultez [Déclencheurs d’Actions : post-challenge - objet API](/docs/fr-ca/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’Authentication API](/docs/fr-ca/secure/multi-factor-authentication/manage-mfa-auth0-apis/manage-authenticator-factors-mfa-api)
* [Configurer les notifications SMS et d’appel vocal pour la MFA](/docs/fr-ca/secure/multi-factor-authentication/multi-factor-authentication-factors/configure-sms-voice-notifications-mfa)
* [Vérification avec des codes de récupération](/docs/fr-ca/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/challenge-with-recovery-codes)
* [Inscrire et vérifier les authentificateurs Email](/docs/fr-ca/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-and-challenge-email-authenticators)
* [Inscrire et vérifier les authentificateurs OTP](/docs/fr-ca/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-and-challenge-otp-authenticators)
* [Inscrire et vérifier les authentificateurs push](/docs/fr-ca/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-and-challenge-push-authenticators)
