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

> Découvrez comment utiliser Hooks pour modifier les scopes et ajouter des claims personnalisés au jeton d’accès obtenu à l’aide du flux d’identification du client.

# Personnaliser les jetons à l’aide de Hooks avec le flux d’identification du client

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

<Warning>
  La date de fin de vie (EOL) de Rules et Hooks est fixée au **18 novembre 2026**, et ils ne sont plus offerts aux nouveaux locataires créés à compter du **16 octobre 2023**. Les locataires existants avec des Hooks actifs conserveront l’accès au produit Hooks jusqu’à sa fin de vie.

  Nous vous recommandons fortement d’utiliser Actions pour étendre Auth0. Avec Actions, vous avez accès à des informations de type riches, à de la documentation intégrée et à des packages `npm` publics, et vous pouvez connecter des intégrations externes qui améliorent votre expérience globale d’extensibilité. Pour en savoir plus sur ce qu’offrent Actions, consultez [Understand How Auth0 Actions Work](/fr-CA/docs/customize/actions/actions-overview).

  Pour vous aider dans votre migration, nous proposons des guides qui vous aideront à [migrate from Rules to Actions](/fr-CA/docs/customize/actions/migrate/migrate-from-rules-to-actions) et à [migrate from Hooks to Actions](/fr-CA/docs/customize/actions/migrate/migrate-from-hooks-to-actions). Nous avons également une page dédiée, [Move to Actions](https://auth0.com/extensibility/movetoactions), qui présente des comparaisons de fonctionnalités, [une démo d’Actions](https://www.youtube.com/watch?v=UesFSY1klrI) et d’autres ressources pour vous accompagner dans votre parcours de migration.

  Pour en savoir plus sur la dépréciation de Rules et Hooks, consultez notre billet de blogue : [Preparing for Rules and Hooks End of Life](https://auth0.com/blog/preparing-for-rules-and-hooks-end-of-life/).
</Warning>

<Warning>
  Comme nous prévoyons supprimer les fonctions Rules et Hooks en 2026, vous ne devriez créer de nouveaux Rules ou Hooks que dans votre environnement de développement, et uniquement pour tester la migration vers Actions.

  Pour savoir comment migrer vos Rules vers Actions, consultez [Migrate from Rules to Actions](/fr-CA/docs/customize/actions/migrate/migrate-from-rules-to-actions). Pour savoir comment migrer vos Hooks vers Actions, consultez [Migrate from Hooks to Actions](/fr-CA/docs/customize/actions/migrate/migrate-from-hooks-to-actions).
</Warning>

Vous pouvez modifier les scopes et ajouter des claims personnalisés dans les jetons émis au moyen du [flux d’identification du client](/fr-CA/docs/get-started/authentication-and-authorization-flow/client-credentials-flow) en ajoutant des [Hooks](/fr-CA/docs/customize/hooks).

Les Hooks vous permettent de personnaliser le comportement d’Auth0 à l’aide de code Node.js. Ce sont des fonctions sécurisées et autonomes associées à des points d’extensibilité précis de la plateforme Auth0 (comme le flux d’identification du client). Auth0 appelle les Hooks dans l’environnement d’exécution pour exécuter votre logique personnalisée.

Vous pouvez gérer les Hooks à l’aide du <Tooltip tip="Auth0 Dashboard : produit principal d’Auth0 pour configurer vos services." cta="Voir le glossaire" href="/fr-CA/docs/glossary?term=Auth0+Dashboard">Auth0 Dashboard</Tooltip> ou de la <Tooltip tip="Auth0 Dashboard : produit principal d’Auth0 pour configurer vos services." cta="Voir le glossaire" href="/fr-CA/docs/glossary?term=Management+API">Management API</Tooltip>.

<Warning>
  Bien que vous puissiez créer plusieurs hooks pour un point d’extensibilité donné, chaque point d’extensibilité ne peut avoir qu’un seul hook activé à la fois. Tous les hooks que vous créez ensuite pour ce point d’extensibilité sont automatiquement désactivés; vous devez donc les activer explicitement. Le hook activé sera exécuté pour toutes les applications et API.
</Warning>

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

Avant de commencer ce tutoriel, vous devez :

* [Enregistrer votre API dans Auth0](/fr-CA/docs/get-started/auth0-overview/set-up-apis)

  * [Ajouter les autorisations d’API appropriées](/fr-CA/docs/get-started/apis/add-api-permissions)
* [Enregistrer l’application M2M dans Auth0](/fr-CA/docs/get-started/auth0-overview/create-applications/machine-to-machine-apps).

  * Sélectionnez **Machine to Machine Applications** comme **Type d’application**.
  * Choisissez l’API que vous avez enregistrée précédemment.
  * Autorisez l’application M2M à appeler votre API.

<div id="steps">
  ## Étapes
</div>

1. **Créer un Hook** : Créez un Hook pour personnaliser votre jeton.
2. **Tester le Hook** : Testez votre nouveau Hook en exécutant un flux d’identification du client et en décodant le jeton d’accès.

<div id="create-a-hook">
  ### Créer un Hook
</div>

Dans cet exemple, vous allez :

* ajouter un claim arbitraire (`https://foo.com/claim`) au [Jeton d’accès](/fr-CA/docs/secure/tokens/access-tokens)
* ajouter une autorisation supplémentaire à l’API que vous avez configurée

Créez un Hook pour personnaliser votre jeton. Lorsque vous serez invité à choisir un point d’extensibilité, sélectionnez `Client Credentials Exchange`, puis ajoutez le code suivant dans l’éditeur :

```js lines theme={null}
module.exports = function(client, scope, audience, context, cb) {
  var access_token = {};
  access_token['https://foo.com/claim'] = 'bar';
  access_token.scope = scope;
  access_token.scope.push('extra');
  cb(null, access_token);
};
```

<Warning>
  Auth0 renvoie les informations de profil sous la forme de revendications structurées, comme le définit la [spécification OpenID Connect (OIDC)](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims). Cela signifie que les claims personnalisés ajoutés aux ID tokens ou aux jetons d’accès doivent [respecter les directives et restrictions](/fr-CA/docs/secure/tokens/json-web-tokens/create-custom-claims) afin d’éviter d’éventuelles collisions.
</Warning>

<div id="test-your-hook">
  ### Testez votre Hook
</div>

Pour tester le Hook que vous venez de créer, vous devez effectuer un Client Credentials Exchange, obtenir le <Tooltip tip="Jeton d’accès : identifiant d’autorisation se présentant sous la forme d’une chaîne opaque ou d’un JWT, utilisé pour accéder à une API." cta="Voir le glossaire" href="/fr-CA/docs/glossary?term=Access+Token">Jeton d’accès</Tooltip>, le décoder et en examiner le contenu.

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

Pour obtenir un jeton, envoyez une requête `POST` au [point de terminaison du flux d’identification du client](https://auth0.com/docs/api/authentication#client-credentials-flow). Assurez-vous de remplacer les valeurs d’espace réservé CLIENT\_ID, CLIENT\_SECRET et API\_IDENTIFIER par l’<Tooltip tip="ID client : valeur d’identification attribuée à votre ressource enregistrée par Auth0." cta="Voir le glossaire" href="/fr-CA/docs/glossary?term=Client+ID">ID client</Tooltip> de votre application, le <Tooltip tip="Secret client : secret utilisé par une application pour s’authentifier auprès du serveur d’autorisation; il ne doit être connu que de l’application et du serveur d’autorisation et doit être suffisamment aléatoire pour ne pas pouvoir être deviné." cta="Voir le glossaire" href="/fr-CA/docs/glossary?term=Client+Secret">Secret client</Tooltip> de votre application et l’identifiant de votre API, respectivement. Vous trouverez l’ID client et le Secret client dans les paramètres de votre [application](https://manage.auth0.com/#/applications), et l’identifiant de l’API dans les paramètres de votre [API](https://manage.auth0.com/#/apis).

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

  ```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=client_credentials&client_id={yourClientId}&client_secret={yourClientSecret}&audience=YOUR_API_IDENTIFIER", 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=client_credentials&client_id={yourClientId}&client_secret={yourClientSecret}&audience=YOUR_API_IDENTIFIER")

  	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=client_credentials&client_id={yourClientId}&client_secret={yourClientSecret}&audience=YOUR_API_IDENTIFIER")
    .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: 'client_credentials',
      client_id: '{yourClientId}',
      client_secret: '{yourClientSecret}',
      audience: 'YOUR_API_IDENTIFIER'
    })
  };

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

  ```php PHP theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://{yourDomain}/oauth/token",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => "grant_type=client_credentials&client_id={yourClientId}&client_secret={yourClientSecret}&audience=YOUR_API_IDENTIFIER",
    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=client_credentials&client_id={yourClientId}&client_secret={yourClientSecret}&audience=YOUR_API_IDENTIFIER"

  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=client_credentials&client_id={yourClientId}&client_secret={yourClientSecret}&audience=YOUR_API_IDENTIFIER"

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

Une réponse réussie comprendra :

* un `access_token`,
* sa durée de validité en secondes (`expires_in`),
* le type de jeton défini à `Bearer` (`token_type`), et
* une permission `extra` (`scope`) (ajoutée par votre Hook)

```json lines theme={null}
HTTP/1.1 200 OK
Content-Type: application/json
{
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik5ESTFNa05DTVRGQlJrVTRORVF6UXpFMk1qZEVNVVEzT1VORk5ESTVSVU5GUXpnM1FrRTFNdyJ9.eyJpc3MiOiJodHRwczovL2RlbW8tYWNjb3VudC5hdXRoMC3jb20vIiwic3ViIjoic0FRSlFpQmYxREw0c2lqSVZCb2pFRUZvcmRoa0o4WUNAY2xpZW50cyIsImF1ZCI6ImRlbW8tYWNjb3VudC5hcGkiLCJleHAiOjE0ODc3NjU8NjYsImlhdCI6MTQ4NzY3OTI2Niwic2NvcGUiOiJyZWFkOmRhdGEgZXh0cmEiLCJodHRwczovL2Zvby5jb20vY2xhaW0iOiKoPXIifQ.da-48mHY_7esfLZpvHWWL8sIH1j_2mUYAB49c-B472lCdsNFvpaLoq6OKQyhnqk9_aW_Xhfkusos3FECTrLFvf-qwQK70QtwbkbVye_IuPSTAYdQ2T-XTzGDm9Nmmy5Iwl9rNYLxVs2OoCdfpVMyda0OaI0AfHBgEdKWluTP67OOnV_dF3KpuwtK3dPKWTCo2j9VCa7X1I4h0CNuM79DHhY2wO7sL8WBej7BSNA3N2TUsp_YTWWfrvsr_vVhJf-32G7w_12ms_PNFUwj2C30ZZIPWc-uEkDztyMLdI-lu9q9TLrLdr0dOhfrtfkdeJx4pUSiHdJHf42kg7UAVK6JcA",
  "expires_in": 86400,
  "scope": "extra",
  "token_type": "Bearer"
}
```

<div id="decode-token">
  #### Décoder le jeton
</div>

Le plus simple pour décoder le jeton d’accès et en examiner le contenu est d’utiliser le [débogueur JWT.io](https://jwt.io/#debugger-io).

Copiez votre jeton d’accès et collez-le dans l’éditeur. Le <Tooltip tip="JSON Web Token (JWT) : format standard des ID Token (et souvent des jetons d’accès), utilisé pour représenter de façon sécurisée des claims entre deux parties." cta="Voir le glossaire" href="/fr-CA/docs/glossary?term=JWT">JWT</Tooltip> est décodé automatiquement et son contenu s’affiche.

Notez que les deux derniers éléments du **payload** ont été définis par votre hook :

* `"scope": "extra"`
* `"https://foo.com/claim": "bar"`

<div id="learn-more">
  ## En savoir plus
</div>

* [Auth0 Hooks](/fr-CA/docs/customize/hooks)
* [Flux d’identification du client](/fr-CA/docs/get-started/authentication-and-authorization-flow/client-credentials-flow)
* [Appelez votre API à l’aide du flux d’identification du client](/fr-CA/docs/get-started/authentication-and-authorization-flow/client-credentials-flow/call-your-api-using-the-client-credentials-flow)
