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

# Révoquer les jetons d'actualisation

> Comment révoquer un jeton d’actualisation compromis à l’aide d’Authentication API, de Management API ou d’Auth0 Dashboard.

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

Vous pouvez révoquer les jetons d’actualisation si ceux-ci sont compromis. Auth0 s’occupe de révoquer les jetons comme s’ils avaient été potentiellement compromis par des entités malveillantes.

You can also use [refresh token rotation](/docs/fr-ca/secure/tokens/refresh-tokens/refresh-token-rotation) so that every time a client exchanges a <Tooltip href="/docs/fr-ca/glossary?term=refresh-token" tip="Jeton d’actualisation
Jeton utilisé pour obtenir un jeton d’accès renouvelé sans obliger les utilisateurs à se connecter à nouveau." cta="Voir le glossaire">refresh token</Tooltip> to get a new <Tooltip href="/docs/fr-ca/glossary?term=access-token" tip="Jeton d’accès
Identifiant d’autorisation, sous la forme d’une chaîne opaque ou d’un JWT, utilisé pour accéder à une API." cta="Voir le glossaire">access token</Tooltip>, a new refresh token is also returned. Par conséquent, vous n’avez plus de jeton d’actualisation de durée de vie plus longue, lequel pourrait offrir un accès illégitime aux ressources. Puisque les jetons d’actualisation sont constamment échangés et invalidés, le risque est diminué.

Vous pouvez révoquer un jeton d’actualisation de plusieurs manières :

* Dans le Dashboard
* Envoyer une demande au point de terminaison `/oauth/revoke` d’Authentication API
* Envoyer une demande au point de terminaison `/api/v2/device-credentials` de <Tooltip href="/docs/fr-ca/glossary?term=management-api" tip="Management API
  Un produit permettant aux clients d’effectuer des tâches administratives." cta="Voir le glossaire">Management API</Tooltip>

## Jetons d’actualisation et autorisations

Une autorisation permet à une application d’accéder à une ressource sur une autre entité sans exposer les identifiants de l’utilisateur. Les jetons sont délivrés dans le contexte d’une autorisation, et lorsqu’une autorisation est révoquée, tous les jetons délivrés dans le contexte de cette autorisation le sont également. En revanche, la révocation d’un jeton n’entraîne pas nécessairement la révocation de l’autorisation.

Vous pouvez choisir le comportement de révocation dans les paramètres du locataire du tableau de bord lorsqu’un appareil est dissocié d’un utilisateur dans Auth0, en utilisant Dashboard ou Management API.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Pour les locataires existants, cette fonctionnalité est activée par défaut pour préserver le comportement existant. Pour les nouveaux locataires (à partir du 13 janvier 2021), cette fonctionnalité est désactivée par défaut pour garantir que la révocation d’un jeton d’actualisation ne révoque pas l’autorisation. Si une révocation d’autorisation est nécessaire, une demande séparée doit être envoyée à partir d’un point de terminaison de révocation d’autorisations.
</Callout>

1. Rendez-vous à [Dashboard > Paramètres du locataire > Avancés](https://manage.auth0.com/#/tenant/advanced) et faites défiler jusqu’à la section **Paramètres**.
2. Activez ou désactivez l’option **La révocation du jeton d’actualisation supprime l’autorisation** en fonction de la manière dont vous souhaitez que la révocation fonctionne.

   1. Activez cette option pour supprimer l’autorisation sous-jacente lorsque vous révoquez le jeton d’actualisation. Chaque demande de révocation invalide non seulement le jeton en question, mais aussi tous les autres jetons basés sur la même autorisation. Cela signifie que tous les jetons d’actualisation émis pour le même utilisateur, la même application et la même audience seront révoqués.
   2. Désactivez l’option pour conserver l’autorisation sous-jacente lorsque vous révoquez le jeton d’actualisation. Lorsqu’un appareil est dissocié, seul le jeton d’actualisation associé est révoqué, ce qui laisse l’autorisation intacte.

## Utiliser le Dashboard

Vous pouvez utiliser Dashboard pour révoquer l’accès autorisé d’un utilisateur à l’application qui a émis le jeton. Cela rend le jeton d’actualisation invalide, ce qui est d’un point de vue fonctionnel identique à la révocation du jeton lui-même.

1. Allez à [Dashboard > Gestion des utilisateurs > Utilisateurs](https://manage.auth0.com/#/users) et cliquez sur le nom de l’utilisateur à afficher.
2. Sélectionnez l’onglet **Applications autorisées**. Cette page répertorie toutes les applications auxquelles l’utilisateur est autorisé à accéder.
3. Pour révoquer l’accès de l’utilisateur à une application autorisée, et donc invalider le jeton d’actualisation, cliquez sur **Révoquer**.

## Utiliser Authentication API

Pour révoquer un jeton d’actualisation, envoyez une demande `POST` à `https://{yourDomain}/oauth/revoke`.

Le point de terminaison `/oauth/revoke` révoque toute l’autorisation, pas seulement un jeton en particulier. Utilisez le point de terminaison `/api/v2/device-credentials` pour révoquer les jetons d’actualisation. L’API valide d’abord les identifiants de l’application, puis vérifie si le jeton a été fourni à l’application qui fait la demande de révocation. Si cette validation échoue, la demande est refusée et l’application est informée de l’erreur. Ensuite, l’API invalide le jeton. L’invalidation a lieu immédiatement et le jeton ne peut plus être utilisé après la révocation. Chaque demande de révocation invalide tous les jetons qui ont été émis pour la même autorisation.

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://{yourDomain}/oauth/revoke' \
    --header 'content-type: application/json' \
    --data '{ "client_id": "{yourClientId}", "client_secret": "{yourClientSecret}", "token": "{yourRefreshToken}" }'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/oauth/revoke");
  var request = new RestRequest(Method.POST);
  request.AddHeader("content-type", "application/json");
  request.AddParameter("application/json", "{ "client_id": "{yourClientId}", "client_secret": "{yourClientSecret}", "token": "{yourRefreshToken}" }", 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/revoke"

  	payload := strings.NewReader("{ "client_id": "{yourClientId}", "client_secret": "{yourClientSecret}", "token": "{yourRefreshToken}" }")

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

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

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

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

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

  }
  ```

  ```java Java theme={null}
  HttpResponse<String> response = Unirest.post("https://{yourDomain}/oauth/revoke")
    .header("content-type", "application/json")
    .body("{ "client_id": "{yourClientId}", "client_secret": "{yourClientSecret}", "token": "{yourRefreshToken}" }")
    .asString();
  ```

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

  var options = {
    method: 'POST',
    url: 'https://{yourDomain}/oauth/revoke',
    headers: {'content-type': 'application/json'},
    data: {
      client_id: '{yourClientId}',
      client_secret: '{yourClientSecret}',
      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/json" };
  NSDictionary *parameters = @{ @"client_id": @"{yourClientId}",
                                @"client_secret": @"{yourClientSecret}",
                                @"token": @"{yourRefreshToken}" };

  NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];

  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://{yourDomain}/oauth/revoke"]
                                                         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/revoke",
    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}", "token": "{yourRefreshToken}" }",
    CURLOPT_HTTPHEADER => [
      "content-type: application/json"
    ],
  ]);

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

  curl_close($curl);

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

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

  conn = http.client.HTTPSConnection("")

  payload = "{ "client_id": "{yourClientId}", "client_secret": "{yourClientSecret}", "token": "{yourRefreshToken}" }"

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

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

  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/json'
  request.body = "{ "client_id": "{yourClientId}", "client_secret": "{yourClientSecret}", "token": "{yourRefreshToken}" }"

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

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

  let headers = ["content-type": "application/json"]
  let parameters = [
    "client_id": "{yourClientId}",
    "client_secret": "{yourClientSecret}",
    "token": "{yourRefreshToken}"
  ] as [String : Any]

  let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

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

Où :

| Attribut                | Description                                                                                                                                                                       |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `client_id`<br />Requis | L’ID client de votre application. L’application doit correspondre à celle pour laquelle le jeton d’actualisation a été émis.                                                      |
| `client_secret`         | Le secret client de votre application. Requis pour les [applications confidentielles](/docs/fr-ca/applications/concepts/app-types-confidential-public#confidential-applications). |
| `token`<br />Required   | Le jeton d’actualisation que vous souhaitez révoquer.                                                                                                                             |

L’application doit correspondre à celle pour laquelle le jeton d’actualisation a été émis.

### Révoquer les jetons sans le secret client

Pour les applications qui ne peuvent pas garder le secret du client en sécurité (comme les applications natives), le point de terminaison `/oauth/revoke` prend en charge l’accès sans secret client. Toutefois, la propriété `tokenEndpointAuthMethod` de l’application elle-même doit être définie sur `none`. Vous pouvez changer la valeur `tokenEndpointAuthMethod`, dans [Dashboard > Applications > Applications](https://manage.auth0.com/#/applications), ou avec Management API.

Si la demande est valide, le jeton d’actualisation est révoqué et la réponse est `HTTP 200`, avec un corps de réponse vide. Dans le cas contraire, le corps de la réponse contient le code d’erreur et la description.

```json lines theme={null}
{
      "error": "invalid_request|invalid_client",
      "error_description": "Description of the error"
    }
```

Réponses possibles :

| Statut HTTP | Description                                                                                                                                                                                                                                               |
| ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 200         | Le jeton d’actualisation est révoqué, n’existe pas ou n’a pas été délivré à l’application qui a fait la demande de révocation. Le corps de la réponse est vide.                                                                                           |
| 400         | Les paramètres requis n’ont pas été envoyés dans la requête (`"error": "invalid_request"`).                                                                                                                                                               |
| 401         | La requête n’est pas autorisée (` "error" : "invalid_request") : "invalid_client"`). Vérifiez que les informations d’identification de l’application (`client_id` et `client_secret`) sont présentes dans la requête et qu’elles ont des valeurs valides. |

## Utiliser Management API

Pour révoquer un jeton d’actualisation à l’aide d’Auth0 Management API, vous avez besoin de l’`id` du jeton d’actualisation que vous souhaitez révoquer. Pour obtenir la liste des jetons d’actualisation existants, appelez [le point de terminaison](/docs/fr-ca/api/management/v2#!/Device_Credentials/get_device_credentials)`/api/v2/device-credentials`, en indiquant `type=refresh_token` et `user_id` avec un jeton d’accès contenant la permission `read:device_credentials`. Pour limiter les résultats, vous pouvez également indiquer le `client_id` associé au jeton (s’il est connu).

export const codeExample11 = `GET https://{yourDomain}/api/v2/device-credentials?
      type=refresh_token
      &client_id=
      &user_id=
    
    {
      "Authorization":   "Bearer {your_access_token}"
    }`;

<AuthCodeBlock children={codeExample11} language="json" />

Le corps de la réponse:

```json lines theme={null}
[
      {
    "id": "dcr_dFJiaAxbEroQ5xxx",
    "device_name": "my-device" // the value of 'device' provided in the /authorize call when creating the token
      }
    ]
```

Pour révoquer un jeton d’actualisation, appelez le point de terminaison `/api/v2/device-credentials` avec un jeton d’accès contenant la permission `delete:device_credentials` et la valeur de l’ID obtenu plus haut :

export const codeExample12 = `DELETE https://{yourDomain}/api/v2/device-credentials/{id}
    
    {
      "Authorization":   "Bearer {your_access_token}"
    }`;

<AuthCodeBlock children={codeExample12} language="javascript" />

La réponse sera `HTTP 204: The credential no longer exists`.

## Considérations et limitations

Avec le [flux d’autorisation d’appareil](/docs/fr-ca/get-started/authentication-and-authorization-flow/device-authorization-flow), la seule manière de forcer un appareil à se réautoriser consiste à révoquer le jeton d’actualisation attribué à cet appareil. Consultez [Dissocier les appareils des utilisateurs](/docs/fr-ca/manage-users/user-accounts/unlink-devices-from-users) pour en savoir plus. L’appareil ne sera pas obligé de se réautoriser tant que le jeton d’accès actuel n’aura pas expiré et que l’application n’aura pas essayé d’utiliser le jeton d’actualisation révoqué.

Avec la [rotation des jetons d’actualisation](/docs/fr-ca/secure/tokens/refresh-tokens/refresh-token-rotation), si un jeton déjà invalidé est utilisé, tous les autres jetons d’actualisation émis après qu’il ait été invalidé seront immédiatement révoqués, exigeant ainsi une nouvelle authentification de la part de l’utilisateur final.

* Utilisez le [point de terminaison](/docs/fr-ca/api/authentication#revoke-refresh-token)`/oauth/revoke` d’Authentication API pour révoquer un jeton d’actualisation. Ce point de terminaison ne supprime pas l’autorisation sous-jacente. Vous pouvez modifier ce comportement pour supprimer également l’autorisation sous-jacente dans Dashboard : [Dashboard > Paramètres du locataire > Avancés](https://manage.auth0.com/#/tenant/advanced). Faites défiler jusqu’à **Paramètres** et activez l’option **La révocation du jeton d’actualisation supprime l’autorisation**.
* Utilisez le [point de terminaison](/docs/fr-ca/api/management/v2#!/Device_Credentials/get_device_credentials)`/api/v2/device-credentials` de Management API pour révoquer des jetons d’actualisation.

## En savoir plus

* [Obtenir des jetons d’actualisation](/docs/fr-ca/secure/tokens/refresh-tokens/get-refresh-tokens)
* [Utilisation des jetons d’actualisation](/docs/fr-ca/secure/tokens/refresh-tokens/use-refresh-tokens)
* [Rotation des jetons d’actualisation](/docs/fr-ca/secure/tokens/refresh-tokens/refresh-token-rotation)
* [Configurer le délai d’expiration du jeton d’actualisation](/docs/fr-ca/secure/tokens/refresh-tokens/configure-refresh-token-expiration)
