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

# Appeler une API à l’aide du flux d’autorisation d’appareil

> Découvrez comment appeler votre API à partir d’un appareil dont les entrées sont limitées, à l’aide du flux d’autorisation d’appareil.

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

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Ce tutoriel vous aidera à appeler votre propre API à partir d’un appareil à entrée limitée en utilisant le flux d’autorisation d’appareil. Pour savoir comment fonctionne le flux et pourquoi vous devriez l’utiliser, consultez [Flux d’autorisation d’appareil](/docs/fr-ca/get-started/authentication-and-authorization-flow/device-authorization-flow).
</Callout>

Auth0 permet à votre application d’implémenter facilement le flux d’autorisation d’appareil en utilisant :

* [Authentication API](/docs/fr-ca/api/authentication) : Poursuivez la lecture pour savoir comment appeler votre API directement. Pour une expérience interactive, veuillez consulter [Terrain de jeu du flux d’appareil](https://auth0.github.io/device-flow-playground/).

## Prérequis

Avant de commencer ce tutoriel :

* Vérifiez les limitations (ci-dessous) pour vous assurer que le flux d’autorisation d’appareil convient à votre mise en œuvre.
* [Register the Application with Auth0 (Enregistrez l’application avec Auth0)](/docs/fr-ca/get-started/auth0-overview/create-applications/native-apps).

  * Sélectionnez un **Application Type (Type d’application)\*\*\*\*Native (Natif)**.
  * Si nécessaire, définissez **Origines Web autorisées**. Vous pouvez ainsi autoriser localhost comme origine lors du développement local, ou pour définir une origine autorisée pour un logiciel TV spécifique avec une architecture soumise à CORS (par exemple, HTML5 + JS). La plupart des applications n’utiliseront pas ce paramètre.
  * Assurez-vous que l’option **OIDC Conformant (Conforme à l’OIDC)** est activée. Ce paramètre se trouve dans [Dashboard](https://manage.auth0.com/#) sous **Applications > Application > Advanced Settings (Paramètres avancés) > OAuth**.
  * Assurez-vous que les **Grant Types (Types d’autorisation)** de l’application comprennent le **Device Code (Code de l’appareil)**. Pour en savoir plus, lisez [Mettre à jour les types d’autorisation](/docs/fr-ca/get-started/applications/update-grant-types).
  * Si vous souhaitez que votre application puisse utiliser des jetons d’actualisation, assurez-vous que les **Types d’autorisation** de l’application comprennent le **Jeton d’actualisation**. Pour en savoir plus, lisez [Mettre à jour les types d’autorisation](/docs/fr-ca/get-started/applications/update-grant-types). Pour en savoir plus sur les jetons d’actualisation, lisez [Jetons d’actualisation](/docs/fr-ca/secure/tokens/refresh-tokens).
* Configurez et activez au moins une connexion pour l’application : [Database connections (Connexions aux bases de données)](/docs/fr-ca/get-started/applications/set-up-database-connections), [Social connections (Connexions sociales)](/docs/fr-ca/authenticate/identity-providers/social-identity-providers)
* [Enregistrez votre application avec Auth0](/docs/fr-ca/architecture-scenarios/mobile-api/part-2#create-the-api)

  * Si vous souhaitez que votre API reçoive des jetons d’actualisation afin d’obtenir de nouveaux jetons lorsque les précédents expirent, activez **Autoriser l’accès hors ligne**. Pour en savoir plus sur les jetons d’actualisation, consultez [Jetons d’actualisation](/docs/fr-ca/secure/tokens/refresh-tokens).
* [Configure Device User Code Settings (Configurez les paramètres du code utilisateur de l’appareil)](/docs/fr-ca/get-started/tenant-settings/configure-device-user-code-settings) pour définir le jeu de caractères, le format et la longueur de votre code utilisateur généré de manière aléatoire.

## Étapes

1. [Demander le code de l’appareil](#request-device-code) (Flux d’appareil) : Demandez un code d’appareil que l’utilisateur peut utiliser pour autoriser l’appareil.
2. [Demander l’activation de l’appareil](#request-device-activation) (Flux d’appareil) : Demandez à l’utilisateur d’autoriser l’appareil à l’aide de son ordinateur portable ou de son téléphone intelligent.
3. [Demander des jetons)](#request-tokens) (Flux d’appareil) : Interrogez le point de terminaison du jeton pour demander un jeton.
4. [Autoriser l’utilisateur](#authorize-user) (Flux du navigateur) : L’utilisateur autorise l’appareil, afin que l’appareil puisse recevoir des jetons.
5. [Recevoir des jetons](#receive-tokens) (Flux d’appareil) : Une fois que l’utilisateur a autorisé avec succès l’appareil, vous pouvez recevoir des jetons.
6. [Appel à l’API](#call-api) (Flux d’appareil) : Utilisez le jeton d’accès récupéré pour appeler votre API.
7. [Jetons d’actualisation](#refresh-tokens) (Flux d’appareil) : Utilisez un jeton d’actualisation pour demander de nouveaux jetons lorsque les anciens expirent.

Facultatif : [Découvrez des cas d’utilisation](#sample-use-cases).

Facultatif : [Dépanner](#troubleshoot).

### Recevoir le code de l’appareil

Une fois que l’utilisateur a démarré l’application de son appareil et souhaite autoriser l’appareil, vous devrez obtenir un code d’appareil. Lorsque l’utilisateur démarre sa session sur son appareil basé sur un navigateur, ce code sera lié à cette session.

Pour obtenir le code de l’appareil, votre application doit demander un code à partir de l’[URLdu code d’appareil](/docs/fr-ca/api/authentication#get-device-code), notamment l’ID client.

#### Exemple POST vers l’URL de code d’appareil

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://{yourDomain}/oauth/device/code' \
    --header 'content-type: application/x-www-form-urlencoded' \
    --data 'client_id={yourClientId}' \
    --data 'scope={scope}' \
    --data 'audience={audience}'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/oauth/device/code");
  var request = new RestRequest(Method.POST);
  request.AddHeader("content-type", "application/x-www-form-urlencoded");
  request.AddParameter("application/x-www-form-urlencoded", "client_id={yourClientId}&scope=%7Bscope%7D&audience=%7Baudience%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/device/code"

  	payload := strings.NewReader("client_id={yourClientId}&scope=%7Bscope%7D&audience=%7Baudience%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 response = Unirest.post("https://{yourDomain}/oauth/device/code")
    .header("content-type", "application/x-www-form-urlencoded")
    .body("client_id={yourClientId}&scope=%7Bscope%7D&audience=%7Baudience%7D")
    .asString();
  ```

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

  var options = {
    method: 'POST',
    url: 'https://{yourDomain}/oauth/device/code',
    headers: {'content-type': 'application/x-www-form-urlencoded'},
    data: {client_id: '{yourClientId}', scope: '{scope}', audience: '{audience}'}
  };

  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:[@"client_id={yourClientId}" dataUsingEncoding:NSUTF8StringEncoding]];
  [postData appendData:[@"&scope={scope}" dataUsingEncoding:NSUTF8StringEncoding]];
  [postData appendData:[@"&audience={audience}" dataUsingEncoding:NSUTF8StringEncoding]];

  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://{yourDomain}/oauth/device/code"]
                                                         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/device/code",
    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}&scope=%7Bscope%7D&audience=%7Baudience%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 = "client_id={yourClientId}&scope=%7Bscope%7D&audience=%7Baudience%7D"

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

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

  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 = "client_id={yourClientId}&scope=%7Bscope%7D&audience=%7Baudience%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: "client_id={yourClientId}".data(using: String.Encoding.utf8)!)
  postData.append("&scope={scope}".data(using: String.Encoding.utf8)!)
  postData.append("&audience={audience}".data(using: String.Encoding.utf8)!)

  let request = NSMutableURLRequest(url: NSURL(string: "https://{yourDomain}/oauth/device/code")! 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>

##### Paramètres du code d’appareil

Veuillez noter que lors de la demande d’un code d’appareil pour appeler une API personnalisée, vous devez procéder ainsi :

* inclure un paramètre <Tooltip data-tooltip-id="react-containers-DefinitionTooltip-0" tip="">audience</Tooltip>,
* éventuellement inclure des permissions supplémentaires prises en charge par l’API cible.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Si votre application ne demande un jeton d’accès que pour récupérer des informations sur l’utilisateur authentifié, aucun paramètre d’audience n’est nécessaire.
</Callout>

| Nom du paramètre | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `client_id`      | L’ID client de votre application. Vous pouvez trouver cette valeur dans vos [Paramètres d’application](https://manage.auth0.com/#/Applications/\{yourClientId}/settings).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `scope`          | Les [permissions](/docs/fr-ca/scopes) pour lesquels vous souhaitez demander une autorisation. Ceux-ci doivent être séparés par un espace. Vous pouvez demander n’importe laquelle des [permissions OIDC standard](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims) concernant les utilisateurs, telles que `profile` et `email`, des [demandes personnalisées](/docs/fr-ca/tokens/concepts/jwt-claims#custom-claims) conformes à un [format d’espace de noms](/docs/fr-ca/tokens/guides/create-namespaced-custom-claims), ou n’importe quelle [permission prise en charge par l’API cible](/docs/fr-ca/scopes/current/api-scopes) (par exemple, `read:contacts`. Incluez `openid` pour obtenir un jeton d’ID ou pour pouvoir utiliser le [point de terminaison /userinfo](/docs/fr-ca/api/authentication#user-profile) pour récupérer les informations de profil de l’utilisateur. Incluez `offline_access` pour obtenir un jeton d’actualisation (assurez-vous que le champ **Autoriser l’accès hors ligne** est activé dans les [Paramètres de l’API](https://manage.auth0.com/#/apis)). Notez que cela doit être codé par URL. |
| `audience`       | L’identifiant unique de l’API à laquelle votre application souhaite accéder. Utilisez la valeur **Identifier** dans l’onglet [Paramètres](https://manage.auth0.com/#/apis) pour l’API que vous avez créée dans le cadre des prérequis de ce tutoriel. Notez que cela doit être codé par URL.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |

#### Réponse du code de l’appareil

Si tout se passe bien, vous recevrez une réponse `HTTP 200` avec une charge utile contenant les valeurs `device_code`, `user_code`, `verification_uri`, `expires_in`, `interval` et `verification_uri_complete`

```json lines theme={null}
{
  "device_code": "Ag_EE...ko1p",
  "user_code": "QTZL-MCBW",
  "verification_uri": "https://accounts.acmetest.org/activate",
  "verification_uri_complete": "https://accounts.acmetest.org/activate?user_code=QTZL-MCBW",
  "expires_in": 900,
  "interval": 5
}
```

* `device_code` est le code unique de l’appareil. Lorsque l’utilisateur accèdera à `verification_uri` sur son appareil basé sur un navigateur, ce code sera lié à sa session.
* `code_utilisateur` contient le code qui doit être saisi dans `verification_uri` pour autoriser l’appareil.
* `verification_uri` contient l’URL que l’utilisateur doit visiter pour autoriser l’appareil.
* `verification_uri_complete` contient l’intégralité de l’URL que l’utilisateur doit visiter pour autoriser l’appareil. Cela permet à votre application d’intégrer le `user_code` dans l’URL, si vous le souhaitez.
* `expires_in` indique la durée de vie (en secondes) des codes `device_code` et `user_code`.
* `interval` indique l’intervalle (en secondes) auquel l’application doit interroger l’URL de jeton pour demander un jeton.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Vous pouvez [configurer le jeu de caractères, le format et la longueur de votre code utilisateur généré de manière aléatoire](/docs/fr-ca/get-started/tenant-settings/configure-device-user-code-settings) dans vos paramètres du locataire.

  Pour empêcher les attaques en force brute, nous imposons les limites suivantes au `user_code` :

  **Longueur minimale** :

  * Lettres BASE20 : 8 caractères
  * Nombres : 9 caractères

  **Longueur maximale** :

  * 20 caractères (tirets et espaces inclus, qui peuvent être ajoutés comme séparateurs pour une meilleure lisibilité)

  **Délai d’expiration** :

  * 15 minutes
</Callout>

### Demande d’activation de l’appareil

Une fois que vous avez reçu un `device_code` et un `user_code` vous devez demander à l’utilisateur d’accéder à `verification_uri` sur son ordinateur portable ou téléphone intelligent et saisir le `user_code` :

<Frame>
  <img src="https://mintcdn.com/docs-dev-actions-triggers-prototype/M4OX-dUcWfCOjXvH/docs/images/fr-ca/cdy7uua7fh8z/2WzaeNXIYCVduRuzyRd0Sb/cdb4d59b657166d0a9a555a662b9ed63/request-device-activation.png?fit=max&auto=format&n=M4OX-dUcWfCOjXvH&q=85&s=b6990d8a3f3226775cee30fa134a6aad" alt="Auth0 Flows Device Authorization Request, sample page showing two activation methods, user_code and QR code" width="1500" height="1082" data-path="docs/images/fr-ca/cdy7uua7fh8z/2WzaeNXIYCVduRuzyRd0Sb/cdb4d59b657166d0a9a555a662b9ed63/request-device-activation.png" />
</Frame>

Le `device_code` n’est pas destiné directement à l’utilisateur et ne doit pas être affiché pendant l’interaction afin de ne pas créer de confusion chez l’utilisateur.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Lorsque vous créez une interface de ligne de commande, vous pouvez ignorer cette étape et ouvrir directement le navigateur avec `verification_uri_complete`.
</Callout>

### Demander des jetons

Pendant que vous attendez que l’utilisateur active l’appareil, commencez à interroger l’URL de jeton pour demander un jeton d’accès. En utilisant l’intervalle d’interrogation (`interval`) extrait de l’étape précédente, vous devrez `POST` sur [l’URL de jeton](/docs/fr-ca/api/authentication#device-auth) en l’envoyant avec le `device_code`.

Pour éviter des erreurs dues à la latence du réseau, vous devez commencer à compter chaque intervalle après la réception de la réponse de la dernière demande d’interrogation.

#### Exemple de demande POST de jeton vers l’URL de jeton.

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://{yourDomain}/oauth/token' \
    --header 'content-type: application/x-www-form-urlencoded' \
    --data grant_type=urn:ietf:params:oauth:grant-type:device_code \
    --data 'device_code={yourDeviceCode}' \
    --data 'client_id={yourClientId}'
  ```

  ```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=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7ByourDeviceCode%7D&client_id={yourClientId}", 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=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7ByourDeviceCode%7D&client_id={yourClientId}")

  	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 response = Unirest.post("https://{yourDomain}/oauth/token")
    .header("content-type", "application/x-www-form-urlencoded")
    .body("grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7ByourDeviceCode%7D&client_id={yourClientId}")
    .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: 'urn:ietf:params:oauth:grant-type:device_code',
      device_code: '{yourDeviceCode}',
      client_id: '{yourClientId}'
    })
  };

  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=urn:ietf:params:oauth:grant-type:device_code" dataUsingEncoding:NSUTF8StringEncoding]];
  [postData appendData:[@"&device_code={yourDeviceCode}" dataUsingEncoding:NSUTF8StringEncoding]];
  [postData appendData:[@"&client_id={yourClientId}" 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=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7ByourDeviceCode%7D&client_id={yourClientId}",
    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=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7ByourDeviceCode%7D&client_id={yourClientId}"

  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=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7ByourDeviceCode%7D&client_id={yourClientId}"

  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=urn:ietf:params:oauth:grant-type:device_code".data(using: String.Encoding.utf8)!)
  postData.append("&device_code={yourDeviceCode}".data(using: String.Encoding.utf8)!)
  postData.append("&client_id={yourClientId}".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>

##### Paramètres de demande de jeton

| Nom du paramètre | Description                                                                                                                                                                                                                                                          |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `grant_type`     | Définir cette option sur « urn:ietf:params:oauth:grant-type:device\_code ». Il s’agit d’un type de subvention d’extension (tel que défini par la section 4.5 de [RFC6749](https://tools.ietf.org/html/rfc6749#section-4.5)). Notez que cela doit être encodé en URL. |
| `device_code`    | Le `device_code` récupéré à l’étape précédente de ce tutoriel.                                                                                                                                                                                                       |
| `client_id`      | L’ID client de votre application. Vous pouvez également trouver cette valeur dans les [Paramètres de l’application](https://manage.auth0.com/#/Applications/\{yourClientId}/settings).                                                                               |

#### Réponses des jetons

Il est possible de recevoir plusieurs réponses `HTTP 4xx` différentes pendant que vous attendez que l’utilisateur autorise l’appareil :

##### Autorisation en attente

Vous verrez cette erreur pendant que vous attendez que l’utilisateur agisse. Poursuivez l’interrogation en utilisant interval suggéré dans l’étape précédente de ce tutoriel.

```json lines theme={null}
HTTP/1.1 403 Forbidden
{
  "error": "authorization_pending",
  "error_description": "..."
}
```

##### Ralentissement

L’interrogation est trop rapide. Ralentissez et utilisez l’intervalle suggéré dans l’étape précédente de ce tutoriel. Pour éviter de recevoir cette erreur en raison de la latence du réseau, vous devez commencer à compter chaque intervalle après la réception de la réponse de la dernière demande d’interrogation.

```json lines theme={null}
HTTP/1.1 429 Too Many Requests
{
  "error": "slow_down",
  "error_description": "..."
}
```

##### Jeton expiré

L’utilisateur n’a pas autorisé l’appareil assez rapidement, par conséquent le `device_code` a expiré. Votre application doit avertir l’utilisateur que le flux a expiré et l’inviter à le réinitialiser.

<Warning>
  L’erreur`expired_token` sera renvoyée exactement une fois. Après cela, `invalid_grant` sera retourné. Votre appareil **doit** cesser de faire des requêtes répétées.
</Warning>

```json lines theme={null}
HTTP/1.1 403 Bad Request
{ 
  "error": "expired_token",
  "error_description": "..."
}
```

##### Accès refusé

Enfin, si l’accès est refusé, vous recevrez :

```json lines theme={null}
HTTP/1.1 403 Forbidden
{
  "error": "access_denied",
  "error_description": "..."
}
```

Cela peut se produire pour diverses raisons, notamment :

* l’utilisateur a refusé d’autoriser l’appareil,
* le serveur d’autorisations a refusé la transaction,
* une règle configurée a refusé l’accès (pour en savoir plus, veuillez consulter [Règles d'Auth0](/docs/fr-ca/customize/rules).)

### Autoriser l’utilisateur

L’utilisateur peut soit balayer le code QR, soit ouvrir la page d’activation et saisir le code d’utilisateur :

<Frame>
  <img src="https://mintcdn.com/docs-dev-actions-triggers-prototype/mxRp7IkiVukPESZw/docs/images/fr-ca/cdy7uua7fh8z/7KRZGb2QcksaEVewXK5bc2/b688b813428f0750ea76b7bcac418bba/enter-user-code__1_.png?fit=max&auto=format&n=mxRp7IkiVukPESZw&q=85&s=1014d84bb81da2de970001311f66213b" alt="Auth0 Flows Device Authorization prompt directing the user to enter the code displayed on their device" width="1350" height="976" data-path="docs/images/fr-ca/cdy7uua7fh8z/7KRZGb2QcksaEVewXK5bc2/b688b813428f0750ea76b7bcac418bba/enter-user-code__1_.png" />
</Frame>

Une page de confirmation s’affiche pour que l’utilisateur confirme qu’il s’agit du bon appareil :

<Frame>
  <img src="https://mintcdn.com/docs-dev-actions-triggers-prototype/6JN7GvC_uhcSr-i5/docs/images/fr-ca/cdy7uua7fh8z/4udH69PJSo20QyK8cwhhtc/193488ee0f689f0724345a40dcdb6478/confirm-device__1_.png?fit=max&auto=format&n=6JN7GvC_uhcSr-i5&q=85&s=402d9bc1b72c5557edea3715e8692229" alt="Auth0 Flows Device Authorization sample confirmation prompt directing the user to confirm the code" width="1351" height="977" data-path="docs/images/fr-ca/cdy7uua7fh8z/4udH69PJSo20QyK8cwhhtc/193488ee0f689f0724345a40dcdb6478/confirm-device__1_.png" />
</Frame>

L’utilisateur terminera la transaction en se connectant. Cette étape peut comprendre un ou plusieurs des procédés suivant :

* Authentifier l’utilisateur;
* Rediriger l’utilisateur vers un fournisseur d’identité pour gérer l’authentification;
* Vérification des sessions actives d’authentification unique (<Tooltip href="/docs/fr-ca/glossary?term=single-sign-on" tip="Authentification unique (SSO)
  Service qui, après qu’un utilisateur se soit connecté à une application, le connecte automatiquement à d’autres applications." cta="Voir le glossaire">SSO</Tooltip>);
* Obtenir le consentement de l’utilisateur pour l’appareil, à moins qu’il n’ait été donné au préalable.

<Frame>
  <img src="https://mintcdn.com/docs-dev-actions-triggers-prototype/6JN7GvC_uhcSr-i5/docs/images/fr-ca/cdy7uua7fh8z/4UbIdGQMucMhoaXxvFLcki/8c1616d7f28bbd37c253a0145a93a17d/user-auth__1_.png?fit=max&auto=format&n=6JN7GvC_uhcSr-i5&q=85&s=9589898b0595449f462a3b7e02d36d0e" alt="Auth0 Flows Device Authorization User authorization prompt directing the user to log in with email and password or with Google or another identity" width="1346" height="995" data-path="docs/images/fr-ca/cdy7uua7fh8z/4UbIdGQMucMhoaXxvFLcki/8c1616d7f28bbd37c253a0145a93a17d/user-auth__1_.png" />
</Frame>

Une fois l’authentification et le consentement obtenus, la demande de confirmation s’affiche :

<Frame>
  <img src="https://mintcdn.com/docs-dev-actions-triggers-prototype/gqbf-XGz7-Z2BrZ6/docs/images/fr-ca/cdy7uua7fh8z/7ze8nZU4b0q3YOzLQSJ6nJ/48ef5170035a200cebb821c581cec9bb/user-confirmation__1_.png?fit=max&auto=format&n=gqbf-XGz7-Z2BrZ6&q=85&s=20365f01a337bbf3656a7956031c309b" alt="Flows - Device Authorization - Congratulations notification for user" width="1345" height="876" data-path="docs/images/fr-ca/cdy7uua7fh8z/7ze8nZU4b0q3YOzLQSJ6nJ/48ef5170035a200cebb821c581cec9bb/user-confirmation__1_.png" />
</Frame>

À ce stade, l’utilisateur s’est authentifié et l’appareil a été autorisé.

### Recevoir les jetons

Pendant que l’utilisateur authentifiait et autorisait l’appareil, l’application de l’appareil a continué à inte]\(/docs/images/RL de jeton pour demander un jeton d’accès.

Une fois que l’utilisateur a autorisé l’appareil avec succès, vous recevrez une réponse `HTTP 200` avec une charge utile contenant les valeurs suivantes `access_token`, `refresh_token` (en option), `id_token` (en option), `token_type`, et `expires_in` :

```json lines theme={null}
{
  "access_token":"eyJz93a...k4laUWw",
  "refresh_token":"GEbRxBN...edjnXbL",
  "id_token": "eyJ0XAi...4faeEoQ",
  "token_type":"Bearer",
  "expires_in":86400
}
```

<Warning>
  Validez vos jetons avant de les enregistrer. Pour en savoir plus, lisez [Valider les jetons d’ID](/docs/fr-ca/secure/tokens/id-tokens/validate-id-tokens) et [Valider les jetons d’accès](/docs/fr-ca/secure/tokens/access-tokens/validate-access-tokens).
</Warning>

Les jetons d’accès sont utilisés pour appeler le point de terminaison [`/userinfo` de](/docs/fr-ca/api/authentication#get-user-info) Auth0 Authentication API ou d’une autre API. Pour en savoir plus sur les jetons d’accès, veuillez consulter [Jetons d’accès](/docs/fr-ca/secure/tokens/access-tokens). Vous pourrez utiliser le jeton d’accès pour appeler `/userinfo` uniquement si vous avez inclus la permission `openid`. Si vous appelez votre propre API, la première chose que votre API devra faire est [vérifier le jeton d’accès](/docs/fr-ca/secure/tokens/access-tokens/validate-access-tokens).

Les jetons d’ID contiennent des informations de l’utilisateur qui doivent être décodées et extraites. (Pour en savoir plus sur les [jetons d’ID](/docs/fr-ca/secure/tokens/id-tokens), veuillez consulter la section correspondante) Le `id_token` ne sera présent dans la réponse que si vous avez inclus la permission `openid`

Les jetons d’actualisation sont utilisés pour obtenir un nouveau jeton d’accès ou un nouveau jeton d’ID après l’expiration du jeton précédent. (Pour en savoir plus sur les jetons d’actualisation, consultez [Jetons d’actualisation](/docs/fr-ca/secure/tokens/refresh-tokens)). Le `refresh_token` ne sera présent dans la réponse que si vous avez inclus la permission `offline_access` et activé **Autoriser l’accès hors ligne** pour votre API dans Dashboard.

<Warning>
  Les jetons d’actualisation doivent être stockés en toute sécurité car ils permettent aux utilisateurs de rester authentifiés pratiquement indéfiniment.
</Warning>

### Appeler votre API

Pour appeler votre API, l’application doit transmettre le jeton d’accès récupéré en tant que jeton du porteur dans l’en-tête d’autorisation de votre requête HTTP.

<AuthCodeGroup>
  ```bash cURL lines theme={null}
  curl --request GET \
    --url https://myapi.com/api \
    --header 'authorization: Bearer ACCESS_TOKEN' \
    --header 'content-type: application/json'
  ```

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

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

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

  func main() {

  	url := "https://myapi.com/api"

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

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

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

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

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

  }
  ```

  ```java Java lines theme={null}
  HttpResponse response = Unirest.get("https://myapi.com/api")
    .header("content-type", "application/json")
    .header("authorization", "Bearer ACCESS_TOKEN")
    .asString();
  ```

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

  var options = {
    method: 'GET',
    url: 'https://myapi.com/api',
    headers: {'content-type': 'application/json', authorization: 'Bearer ACCESS_TOKEN'}
  };

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

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

  NSDictionary *headers = @{ @"content-type": @"application/json",
                             @"authorization": @"Bearer ACCESS_TOKEN" };

  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://myapi.com/api"]
                                                         cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                     timeoutInterval:10.0];
  [request setHTTPMethod:@"GET"];
  [request setAllHTTPHeaderFields:headers];

  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 lines expandable theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://myapi.com/api",
    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 ACCESS_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 lines theme={null}
  import http.client

  conn = http.client.HTTPSConnection("myapi.com")

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

  conn.request("GET", "/api", headers=headers)

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

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

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

  url = URI("https://myapi.com/api")

  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["content-type"] = 'application/json'
  request["authorization"] = 'Bearer ACCESS_TOKEN'

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

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

  let headers = [
    "content-type": "application/json",
    "authorization": "Bearer ACCESS_TOKEN"
  ]

  let request = NSMutableURLRequest(url: NSURL(string: "https://myapi.com/api")! as URL,
                                          cachePolicy: .useProtocolCachePolicy,
                                      timeoutInterval: 10.0)
  request.httpMethod = "GET"
  request.allHTTPHeaderFields = headers

  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>

### Jetons d’actualisation

Vous avez déjà reçu un jeton d’actualisation si vous avez suivi ce tutoriel et complété ce qui suit :

* configuré votre API pour autoriser l’accès hors ligne
* inclus la permission `offline_access` lorsque vous avez lancé la demande d’authentification via le [authorize endpoint (point de terminaison d’autorisation)](/docs/fr-ca/api/authentication/reference#authorize-application)

Vous pouvez utiliser le jeton d’actualisation pour obtenir un nouveau jeton d’accès. Généralement, un utilisateur aura besoin d’un nouveau jeton d’accès uniquement après l’expiration du précédent ou lorsqu’il accède à une nouvelle ressource pour la première fois. Il est déconseillé d’appeler le point de terminaison pour obtenir un nouveau jeton d’accès à chaque fois que vous appelez une API, et Auth0 impose des limites anti-attaques qui réduiront la quantité de requêtes au point de terminaison pouvant être exécutées en utilisant le même jeton depuis la même adresse IP.

Pour actualiser votre jeton, effectuez une requête `POST` au point de terminaison `/oauth/token` dans l’Authentication API, à l’aide de `grant_type=refresh_token`.

#### Exemple de jeton d’actualisation POST vers l’URL de jeton.

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://{yourDomain}/oauth/token' \
    --header 'content-type: application/x-www-form-urlencoded' \
    --data grant_type=refresh_token \
    --data 'client_id={yourClientId}' \
    --data 'client_secret={yourClientSecret}' \
    --data 'refresh_token={yourRefreshToken}'
  ```

  ```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=refresh_token&client_id={yourClientId}&client_secret={yourClientSecret}&refresh_token=%7ByourRefreshToken%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=refresh_token&client_id={yourClientId}&client_secret={yourClientSecret}&refresh_token=%7ByourRefreshToken%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 response = Unirest.post("https://{yourDomain}/oauth/token")
    .header("content-type", "application/x-www-form-urlencoded")
    .body("grant_type=refresh_token&client_id={yourClientId}&client_secret={yourClientSecret}&refresh_token=%7ByourRefreshToken%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: 'refresh_token',
      client_id: '{yourClientId}',
      client_secret: '{yourClientSecret}',
      refresh_token: '{yourRefreshToken}'
    })
  };

  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=refresh_token" dataUsingEncoding:NSUTF8StringEncoding]];
  [postData appendData:[@"&client_id={yourClientId}" dataUsingEncoding:NSUTF8StringEncoding]];
  [postData appendData:[@"&client_secret={yourClientSecret}" dataUsingEncoding:NSUTF8StringEncoding]];
  [postData appendData:[@"&refresh_token={yourRefreshToken}" 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=refresh_token&client_id={yourClientId}&client_secret={yourClientSecret}&refresh_token=%7ByourRefreshToken%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=refresh_token&client_id={yourClientId}&client_secret={yourClientSecret}&refresh_token=%7ByourRefreshToken%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=refresh_token&client_id={yourClientId}&client_secret={yourClientSecret}&refresh_token=%7ByourRefreshToken%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=refresh_token".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("&refresh_token={yourRefreshToken}".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>

##### Paramètres de requête de jeton d’actualisation

| Nom du paramètre | Description                                                                                                                                                                                                                                                                       |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `grant_type`     | Définissez sur « refresh\_token ».                                                                                                                                                                                                                                                |
| `client_id`      | L’ID client de votre application. Vous pouvez trouver cette valeur dans \[Paramètres de l’application] ([https://manage.auth0.com/#/Applications/\{yourClientId}/settings](https://manage.auth0.com/#/Applications/\{yourClientId}/settings)).                                    |
| `client_secret`  | Le secret client de votre application. Vous pouvez trouver cette valeur dans \[Paramètres de l’application] ([https://manage.auth0.com/#/Applications/\{yourClientSecret}/settings](https://manage.auth0.com/#/Applications/\{yourClientSecret}/settings)).                       |
| `refresh_token`  | Le jeton d’actualisation à utiliser.                                                                                                                                                                                                                                              |
| `scope`          | (Facultatif) Une liste délimitée par des espaces des autorisations de permissions requises. Si elles ne sont pas envoyées, les permissions d’origine seront utilisées; sinon, vous pouvez demander un ensemble réduit de permissions. Veuillez noter que cela doit être codé URL. |

#### Réponse du jeton d’actualisation

Si tout se passe bien, vous recevrez une réponse `HTTP 200` avec une charge utile contenant un nouveau `access_token`, `id_token` (en option), durée de vie du jeton en secondes (`expires_in`), valeurs de `scope` accordées et `token_type` :

```json lines theme={null}
{
  "access_token": "eyJ...MoQ",
  "expires_in": 86400,
  "scope": "openid offline_access",
  "id_token": "eyJ...0NE",
  "token_type": "Bearer"
}
```

<Warning>
  Validez vos jetons avant de les enregistrer. Pour en savoir plus, lisez [Valider les jetons d’ID](/docs/fr-ca/secure/tokens/id-tokens/validate-id-tokens) et [Valider les jetons d’accès](/docs/fr-ca/secure/tokens/access-tokens/validate-access-tokens).
</Warning>

## Exemples de cas d’utilisation

### Détecter l’utilisation du flux d’autorisation d’appareil

Vous pouvez utiliser des règles pour détecter si la transaction en cours utilise le flux d’autorisation d’appareil. (Pour en savoir plus sur les règles, lisez l’article [Règles d'Auth0](/docs/fr-ca/customize/rules)). Pour cela, vérifiez la propriété `protocol` de l’objet `context` :

```javascript lines theme={null}
function (user, context, callback) {
   if (context.protocol === 'oauth2-device-code') {
      ...
   }
 
   callback(null, user, context);
}
```

### Exemples de mises en œuvre

* [Terrain de jeu du flux de l’appareil](https://auth0.github.io/device-flow-playground/)
* [AppleTV (Swift)](https://github.com/pushpabrol/auth0-device-flow-appletv) : application simple qui montre comment Auth0 peut être utilisé avec le flux d’autorisation d’appareil AppleTV.
* [Interface de ligne de commande (Node.js)](https://gist.github.com/panva/ebaacfe433a8677bdbf458f6e1132045) : exemple de mise en œuvre d’une interface de ligne de commande qui utilise le flux d’autorisation d’un appareil au lieu du flux du code d’autorisation. La principale différence est que votre interface de ligne de commande n’a pas besoin d’héberger un serveur Web et d’écouter sur un port.

## Dépanner

Les journaux de locataires sont créés pour toutes les interactions qui ont lieu et peuvent être utilisés pour résoudre les problèmes. Pour en savoir plus, lisez [Logs (Journaux)](/docs/fr-ca/deploy-monitor/logs).

### Codes d’erreur

| Code    | Nom                                                              | Description                              |
| ------- | ---------------------------------------------------------------- | ---------------------------------------- |
| `fdeaz` | Échec de la demande d’autorisation de l’appareil                 |                                          |
| `fdeac` | Échec de l’activation de l’appareil                              |                                          |
| `fdecc` | L’utilisateur a annulé la confirmation de l’appareil             |                                          |
| `fede`  | Échec de l’échange du code de l’appareil contre le jeton d’accès |                                          |
| `sede`  | Réussite de l’échange                                            | Code de l’appareil pour le jeton d’accès |

### Limites

Pour utiliser le flux d’autorisation d’appareil, les appareils doivent :

* Prendre en charge Support Server Name Indication (SNI) (Indication du nom du serveur) lorsque des [Custom Domains (Domaines personnalisés) sont utilisés](/docs/fr-ca/customize/custom-domains)
* Avoir une [Auth0 Application Type (Type d’application Auth0)](/docs/fr-ca/get-started/applications)**Native (Natif)**
* Avoir la [Token Endpoint Authentication Method (Méthode d’authentification du point de terminaison du jeton)](/docs/fr-ca/get-started/applications/application-settings) définie sur **None (Aucune)**
* Être [OIDC-conformant (conforme à l’OIDC)](/docs/fr-ca/get-started/applications/application-settings)
* Ne pas être créée au moyen de [Dynamic Client Registration (Enregistrement dynamique des clients)](/docs/fr-ca/get-started/applications/dynamic-client-registration)

En outre, le flux d’autorisation d’appareil ne permet pas :

* Les [Social Connections (Connexions sociales)](/docs/fr-ca/authenticate/identity-providers/social-identity-providers) qui utilisent les [Auth0 developer keys (Clés de développeur Auth0)](/docs/fr-ca/authenticate/identity-providers/social-identity-providers/devkeys), sauf si vous utilisez la  [Universal Login experience (Expérience de connexion universelle)](/docs/fr-ca/authenticate/login/auth0-universal-login/universal-login-vs-classic-login/universal-experience).
* Les paramètres de la chaîne de requête doivent être accessibles à partir d’une page de connexion ou de règles hébergées.
* [Association de comptes d’utilisateur](/docs/fr-ca/manage-users/user-accounts/user-account-linking)

Nous prenons en charge l’intégralité du Draft 15, à l’exception des clients confidentiels. Pour en savoir plus, veuillez consulter [OAuth 2.0 Device Authorization Grant Draft 15 sur ietf.org](https://tools.ietf.org/html/draft-ietf-oauth-device-flow-15).

## En savoir plus

* [Cadre d’applications Authorization OAuth 2.0](/docs/fr-ca/authenticate/protocols/oauth)
* [Protocole OpenID Connect](/docs/fr-ca/authenticate/protocols/openid-connect-protocol)
* [Jetons](/docs/fr-ca/secure/tokens)
* [Journaux](/docs/fr-ca/deploy-monitor/logs)
