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

# Défi-réponse avec les codes de récupération

> Décrit comment utiliser l’API MFA pour lancer un défi-réponse aux utilisateurs qui perdent l’accès à leur appareil ou à leur compte à l’aide de codes de récupération.

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>;
};

Lorsque les [codes de récupération sont activés](/docs/fr-ca/secure/multi-factor-authentication/configure-recovery-codes-for-mfa) pour votre locataire, Auth0 les génère automatiquement lorsqu’un utilisateur s’inscrit avec l’authentification multifacteur (<Tooltip href="/docs/fr-ca/glossary?term=multifactor-authentication" 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, tel qu’un code par SMS." cta="Voir le glossaire">MFA</Tooltip>). L’utilisateur doit enregistrer le code de récupération. Ce code pourra être utilisé ultérieurement si l’utilisateur perd l’accès à l’appareil ou au compte utilisé pour la MFA.

Lorsque les codes de récupération sont désactivés, l’API de MFA ne renvoie pas de code de récupération lorsque vous associez le premier facteur MFA d’un utilisateur et que les utilisateurs ne peuvent pas s’authentifier avec un code de récupération.

Vous pouvez autoriser les utilisateurs à s’authentifier avec un code de récupération à l’aide de l’API MFA.

1. Demandez à l’utilisateur son code de récupération. Cette valeur doit être saisie dans l’application pour que l’utilisateur puisse s’authentifier.

   <Callout icon="file-lines" color="#0EA5E9" iconType="regular">
     Auth0 ne génère pas de codes de récupération pour DUO et pour l’ancien facteur `google-authenticator`.
   </Callout>

2. Authentifiez-vous avec le code de récupération. Appelez le point de terminaison OAuth Token avec le code de récupération pour vous authentifier et générer un nouveau code de récupération. Vous devez préciser les paramètres suivants :

| Paramètre       | Valeur                                                |
| --------------- | ----------------------------------------------------- |
| `grant_type`    | `http://auth0.com/oauth/grant-type/mfa-recovery-code` |
| `recovery_code` | Le code de récupération fourni par l’utilisateur.     |

<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-recovery-code \
  --data 'client_id={yourClientId}' \
  --data 'client_secret={yourClientSecret}' \
  --data 'mfa_token={mfaToken}' \
  --data 'recovery_code={recoveryCode}'

  ```

  ```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-recovery-code&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&mfa_token=%7BmfaToken%7D&recovery_code=%7BrecoveryCode%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-recovery-code&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&mfa_token=%7BmfaToken%7D&recovery_code=%7BrecoveryCode%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-recovery-code&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&mfa_token=%7BmfaToken%7D&recovery_code=%7BrecoveryCode%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-recovery-code',
     client_id: '{yourClientId}',
     client_secret: '{yourClientSecret}',
     mfa_token: '{mfaToken}',
     recovery_code: '{recoveryCode}'
  })
  };

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

  ```

  ```objc Obj-C theme={null}
     #import <Foundation/Foundation.h>

  NSDictionary *headers = @{ @"content-type": @"application/x-www-form-urlencoded" };

  NSMutableData *postData = [[NSMutableData alloc] initWithData:[@"grant_type=http://auth0.com/oauth/grant-type/mfa-recovery-code" dataUsingEncoding:NSUTF8StringEncoding]];
  [postData appendData:[@"&client_id={yourClientId}" dataUsingEncoding:NSUTF8StringEncoding]];
  [postData appendData:[@"&client_secret={yourClientSecret}" dataUsingEncoding:NSUTF8StringEncoding]];
  [postData appendData:[@"&mfa_token={mfaToken}" dataUsingEncoding:NSUTF8StringEncoding]];
  [postData appendData:[@"&recovery_code={recoveryCode}" dataUsingEncoding:NSUTF8StringEncoding]];

  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://{yourDomain}/oauth/token"]
                                                        cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                     timeoutInterval:10.0];
  [request setHTTPMethod:@"POST"];
  [request setAllHTTPHeaderFields:headers];
  [request setHTTPBody:postData];

  NSURLSession *session = [NSURLSession sharedSession];
  NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                  if (error) {
                                                     NSLog(@"%@", error);
                                                  } else {
                                                     NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                     NSLog(@"%@", httpResponse);
                                                  }
                                            }];
  [dataTask resume];

  ```

  ```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-recovery-code&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&mfa_token=%7BmfaToken%7D&recovery_code=%7BrecoveryCode%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-recovery-code&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&mfa_token=%7BmfaToken%7D&recovery_code=%7BrecoveryCode%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-recovery-code&client_id={yourClientId}&client_secret=%7ByourClientSecret%7D&mfa_token=%7BmfaToken%7D&recovery_code=%7BrecoveryCode%7D"

  response = http.request(request)
  puts response.read_body

  ```

  ```swift Swift theme={null}
     import Foundation

  let headers = ["content-type": "application/x-www-form-urlencoded"]

  let postData = NSMutableData(data: "grant_type=http://auth0.com/oauth/grant-type/mfa-recovery-code".data(using: String.Encoding.utf8)!)
  postData.append("&client_id={yourClientId}".data(using: String.Encoding.utf8)!)
  postData.append("&client_secret={yourClientSecret}".data(using: String.Encoding.utf8)!)
  postData.append("&mfa_token={mfaToken}".data(using: String.Encoding.utf8)!)
  postData.append("&recovery_code={recoveryCode}".data(using: String.Encoding.utf8)!)

  let request = NSMutableURLRequest(url: NSURL(string: "https://{yourDomain}/oauth/token")! as URL,
                                         cachePolicy: .useProtocolCachePolicy,
                                      timeoutInterval: 10.0)
  request.httpMethod = "POST"
  request.allHTTPHeaderFields = headers
  request.httpBody = postData as Data

  let session = URLSession.shared
  let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
     print(error)
  } else {
     let httpResponse = response as? HTTPURLResponse
     print(httpResponse)
  }
  })

  dataTask.resume()

  ```
</AuthCodeGroup>

3. Invitez l’utilisateur à recueillir le code de récupération. Si l’appel réussit, vous obtiendrez les jetons d’authentification et un nouveau code de récupération :

   ```json lines theme={null}
   {
       "access_token": "O3...H4",
       "id_token": "eyJh...w",
       "scope": "openid profile",
       "expires_in": 86400,
       "recovery_code": "K6LGLV3RSH3VERMKET8L7QKU",
       "token_type": "Bearer"
   }
   ```

4. Avertissez l’utilisateur qu’un nouveau code de récupération a été généré et demandez-lui de le recueillir.

## En savoir plus

* [Facteurs d’authentification SMS et vocaux pour l’inscription et les défis de connexion](/docs/fr-ca/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-challenge-sms-voice-authenticators)
* [Inscrire et lancer un défi-réponse pour les authentifiants Push](/docs/fr-ca/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-and-challenge-push-authenticators)
* [Inscription et défi des authentificateurs OTP](/docs/fr-ca/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-and-challenge-otp-authenticators)
* [Inscription et authentifiants par défi-réponse avec courriel](/docs/fr-ca/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-and-challenge-email-authenticators)
* [API MFA Auth0](/docs/fr-ca/secure/multi-factor-authentication/multi-factor-authentication-developer-resources/mfa-api)
* [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)
