> ## 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 de notification push comme facteur d’authentification.

# Inscrire des authentificateurs par notification push et lancer des demandes de vérification

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 fournit un flux intégré d’inscription à la <Tooltip tip="Authentification multifacteur (MFA) : processus d’authentification qui utilise un facteur supplémentaire 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 le faire.

Vous pouvez inscrire les utilisateurs et leur envoyer des demandes de vérification par notifications push avec l’application Guardian ou le SDK à l’aide de l’API MFA.

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

Avant de pouvoir utiliser les API de 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 la notification push](/fr-CA/docs/secure/multi-factor-authentication/multi-factor-authentication-factors/configure-push-notifications-for-mfa) comme facteur 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-push">
  ## Inscription par notification push
</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="/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 le 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>

Effectuez 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.

Pour l’inscription avec push, définissez le paramètre `authenticator_types` sur `[oob]` et le paramètre `oob_channels` sur `[auth0]`.

<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": ["auth0"] }'
  ```

  ```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": ["auth0"] }", 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": ["auth0"] }")

  	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": ["auth0"] }")
    .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: ['auth0']}
  };

  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": ["auth0"] }",
    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": ["auth0"] }"

  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": ["auth0"] }"

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

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

```json lines theme={null}
{
    "authenticator_type": "oob",
    "barcode_uri": "otpauth://totp/tenant:user?enrollment_tx_id=qfjn2eiNYSjU3xID7dBYeCBSrdREWJPY&base_url=tenan",
    "recovery_codes": [
        "ALKE6EJZ4853BJYLM2DM2WU7"
    ],
    "oob_channel": "auth0",
    "oob_code": "Fe26.2...SYAg"
}
```

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 d’abord lui demander de s’authentifier avec le 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 facteur d’authentification secondaire. Ces codes ne peuvent être utilisés qu’une seule fois, et de nouveaux codes sont générés au besoin.

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

Pour confirmer l’inscription, l’utilisateur final devra scanner un code QR à l’aide du `barcode_uri` dans l’application Guardian, au cours des 5 prochaines minutes.

Une fois cela fait, l’application Guardian informera Auth0 que l’utilisateur s’est inscrit avec succès. Pour vérifier si cela s’est produit, interrogez le point de terminaison de jeton d’Auth0 <Tooltip tip="Point de terminaison de jeton : point de terminaison sur le serveur d’autorisation utilisé pour demander des jetons par programmation." cta="Voir le glossaire" href="/fr-CA/docs/glossary?term=Token+endpoint">point de terminaison de jeton</Tooltip> avec le `oob_code` renvoyé par l’appel au point de terminaison MFA Associate.

<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}'
  ```

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

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

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

  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_NONE

  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"

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

Si l’utilisateur n’a pas scanné le code, une réponse `authorization_pending` sera renvoyée, ce qui indique que vous devez appeler `oauth_token` de nouveau dans quelques secondes :

```json lines theme={null}
{
    "error": "authorization_pending",
    "error_description": "Authorization pending: please repeat the request in a few seconds."
}
```

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 correctement 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`.

<div id="challenge-with-push">
  ## Demande de vérification par notification push
</div>

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

Obtenez un jeton MFA en suivant les étapes décrites dans [S’authentifier avec le flux Resource Owner Password Grant et l’authentification 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 soumettre l’utilisateur à une demande de vérification, vous avez besoin de l’`authenticator_id` du facteur que vous voulez vérifier. Vous pouvez lister 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>

Vous obtiendrez une liste d’authentificateurs au format suivant :

```json lines theme={null}
[
    {
        "id": "recovery-code|dev_Ahb2Tb0ujX3w7ilC",
        "authenticator_type": "recovery-code",
        "active": true
    },
    {
        "id": "push|dev_ZUla9SQ6tAIHSz6y",
        "authenticator_type": "oob",
        "active": true,
        "oob_channel": "auth0",
        "name": "user's device name"
    },
    {
        "id": "totp|dev_gJ6Y6vpSrjnKeT67",
        "authenticator_type": "otp",
        "active": true
    }
]
```

Lorsque les utilisateurs s’inscrivent avec push, ils sont également inscrits à l’OTP, puisque Guardian prend en charge [la vérification par OTP](/fr-CA/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-and-challenge-otp-authenticators) dans les cas où l’utilisateur n’a pas de connexion.

<div id="challenge-user-with-push">
  ### Demander une confirmation push à l’utilisateur
</div>

Pour déclencher une demande de confirmation push, 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": "push|dev_ZUla9SQ6tAIHSz6y", "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": "push|dev_ZUla9SQ6tAIHSz6y", "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": "push|dev_ZUla9SQ6tAIHSz6y", "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": "push|dev_ZUla9SQ6tAIHSz6y", "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: 'push|dev_ZUla9SQ6tAIHSz6y',
      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": "push|dev_ZUla9SQ6tAIHSz6y", "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": "push|dev_ZUla9SQ6tAIHSz6y", "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": "push|dev_ZUla9SQ6tAIHSz6y", "mfa_token": "{mfaToken}" }"

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

<div id="complete-authentication-using-received-code">
  ### Terminer 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": "Fe26...jGco"
}
```

Votre application doit interroger régulièrement le point de terminaison OAuth0 Token jusqu’à ce que l’utilisateur accepte la notification push.

<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}'
  ```

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

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

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

  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"

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

L’appel peut renvoyer l’un des résultats suivants :

| Résultat                           | Description                                                                                      |
| ---------------------------------- | ------------------------------------------------------------------------------------------------ |
| `authorization_pending`            | Erreur : si la demande de vérification n’a pas encore été acceptée ni rejetée.                   |
| `slow_down`                        | Erreur : si l’interrogation est trop fréquente.                                                  |
| `access_token` and `refresh_token` | Si la demande de vérification a été acceptée; il faut cesser l’interrogation à ce stade.         |
| `invalid_grant`                    | Erreur : si la demande de vérification a été rejetée; il faut cesser l’interrogation à ce stade. |

<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 accès anticipé. En utilisant cette fonctionnalité, vous acceptez les conditions applicables de l’essai gratuit prévues dans le [Master Subscription Agreement](https://www.okta.com/legal/) d’Okta. Pour en savoir plus sur les phases de lancement d’Auth0, consultez [Product Release Stages](/fr-CA/docs/troubleshoot/product-lifecycle/product-release-stages). Pour participer à l’accès anticipé, communiquez avec l’[assistance Auth0](https://support.auth0.com/).
</Warning>

La MFA personnalisable permet aux utilisateurs de s’inscrire et de faire des demandes de vérification au moyen des 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`, qui contient 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 auxquels l’utilisateur s’est inscrit et de repérer le même type que celui pris en charge par votre application.  Vous devez aussi obtenir l’`authenticator_type` correspondant pour émettre 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 demande de 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’Authentication API](/fr-CA/docs/secure/multi-factor-authentication/manage-mfa-auth0-apis/manage-authenticator-factors-mfa-api)
* [Configurer les notifications push pour la MFA](/fr-CA/docs/secure/multi-factor-authentication/multi-factor-authentication-factors/configure-push-notifications-for-mfa)
* [Lancer une demande de vérification avec des codes de récupération](/fr-CA/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/challenge-with-recovery-codes)
* [Inscrire les authentificateurs par courriel et lancer des demandes de vérification](/fr-CA/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-and-challenge-email-authenticators)
* [Inscrire les authentificateurs OTP et lancer des demandes de vérification](/fr-CA/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-and-challenge-otp-authenticators)
* [Inscrire les authentificateurs par SMS et appel vocal et lancer des demandes de vérification](/fr-CA/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-challenge-sms-voice-authenticators)
