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

# Changer les images utilisateur

> Apprenez à utiliser les métadonnées utilisateur pour modifier le champ d’image d’un utilisateur et comment changer la photo par défaut pour tous les utilisateurs.

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
              processedNode = processedNode.replaceAll(new RegExp(escapedKey, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****MASKED*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

Auth0 normalise les propriétés de profil commun dans le profil utilisateur : `name`, `picture`, etc. Le champ relatif à l’image est alimenté soit par l’image de profil du fournisseur social, soit par l’image Gravatar associée à l’adresse courriel de l’utilisateur.

Par défaut, tous les utilisateurs de la base de données auront une image de remplacement avec leurs initiales. Lorsque vous authentifiez un utilisateur, ce champ d’image est appelé `user.picture`.

## Utiliser Management API

L’attribut `user.picture` n’est pas directement modifiable lorsqu’il est fourni par des fournisseurs d’identité autres qu’Auth0, tels que Google, Facebook ou encore X. Pour modifier cet attribut, vous devez configurer votre synchronisation de connexion avec Auth0 de manière à ce que les attributs de l’utilisateur soient mis à jour à partir du fournisseur d’identité uniquement lors de la création du profil utilisateur. Pour en savoir plus, consultez [Configurer la connexion du fournisseur d’identité pour les mises à jour du profil utilisateur](/docs/fr-ca/manage-users/user-accounts/user-profiles/configure-connection-sync-with-auth0). Ces attributs racine seront alors disponibles pour modification individuelle ou pour une importation en bloc à l’aide de Management API. Pour en savoir plus, consultez [Importations en bloc d’utilisateurs](/docs/fr-ca/manage-users/user-migration/bulk-user-imports).

Alternativement, vous pouvez utiliser des métadonnées pour stocker l’attribut d’image pour les utilisateurs. Par exemple, si votre application permet de télécharger des photos de profil, une fois la photo téléchargée, vous pouvez définir l’URL de l’image dans `user.user_metadata.picture` :

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request PATCH \
    --url 'https://{yourDomain}/api/v2/users/USER_ID' \
    --header 'authorization: Bearer MGMT_API_ACCESS_TOKEN' \
    --header 'content-type: application/json' \
    --data '{"user_metadata": {"picture": "https://example.com/some-image.png"}}'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/api/v2/users/USER_ID");
  var request = new RestRequest(Method.PATCH);
  request.AddHeader("authorization", "Bearer MGMT_API_ACCESS_TOKEN");
  request.AddHeader("content-type", "application/json");
  request.AddParameter("application/json", "{"user_metadata": {"picture": "https://example.com/some-image.png"}}", 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}/api/v2/users/USER_ID"

  	payload := strings.NewReader("{"user_metadata": {"picture": "https://example.com/some-image.png"}}")

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

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

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

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

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

  }
  ```

  ```java Java theme={null}
  HttpResponse<String> response = Unirest.patch("https://{yourDomain}/api/v2/users/USER_ID")
    .header("authorization", "Bearer MGMT_API_ACCESS_TOKEN")
    .header("content-type", "application/json")
    .body("{"user_metadata": {"picture": "https://example.com/some-image.png"}}")
    .asString();
  ```

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

  var options = {
    method: 'PATCH',
    url: 'https://{yourDomain}/api/v2/users/USER_ID',
    headers: {
      authorization: 'Bearer MGMT_API_ACCESS_TOKEN',
      'content-type': 'application/json'
    },
    data: {user_metadata: {picture: 'https://example.com/some-image.png'}}
  };

  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 = @{ @"authorization": @"Bearer MGMT_API_ACCESS_TOKEN",
                             @"content-type": @"application/json" };
  NSDictionary *parameters = @{ @"user_metadata": @{ @"picture": @"https://example.com/some-image.png" } };

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

  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://{yourDomain}/api/v2/users/USER_ID"]
                                                         cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                     timeoutInterval:10.0];
  [request setHTTPMethod:@"PATCH"];
  [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}/api/v2/users/USER_ID",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "PATCH",
    CURLOPT_POSTFIELDS => "{"user_metadata": {"picture": "https://example.com/some-image.png"}}",
    CURLOPT_HTTPHEADER => [
      "authorization: Bearer MGMT_API_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 theme={null}
  import http.client

  conn = http.client.HTTPSConnection("")

  payload = "{"user_metadata": {"picture": "https://example.com/some-image.png"}}"

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

  conn.request("PATCH", "/{yourDomain}/api/v2/users/USER_ID", 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}/api/v2/users/USER_ID")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Patch.new(url)
  request["authorization"] = 'Bearer MGMT_API_ACCESS_TOKEN'
  request["content-type"] = 'application/json'
  request.body = "{"user_metadata": {"picture": "https://example.com/some-image.png"}}"

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

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

  let headers = [
    "authorization": "Bearer MGMT_API_ACCESS_TOKEN",
    "content-type": "application/json"
  ]
  let parameters = ["user_metadata": ["picture": "https://example.com/some-image.png"]] as [String : Any]

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

  let request = NSMutableURLRequest(url: NSURL(string: "https://{yourDomain}/api/v2/users/USER_ID")! as URL,
                                          cachePolicy: .useProtocolCachePolicy,
                                      timeoutInterval: 10.0)
  request.httpMethod = "PATCH"
  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>

## Utiliser les Actions

Pour s’assurer que l’image des `user_metadata` est renvoyée dans le jeton d’ID, nous allons devoir [créer une nouvelle action](/docs/fr-ca/customize/actions/write-your-first-action) pour vérifier si l’attribut `event.user.user_metadata.picture` est présent et, si c’est le cas, remplacer l’attribut `user.picture` par cette valeur. Vous serez ainsi certain que l’image des `user_metadata` sera renvoyée dans la demande `picture` du jeton d’ID.

1. Allez à [Auth0 Dashboard > Actions > Library (Bibliothèque)](https://manage.auth0.com/#/actions/library) et sélectionnez **Build Custom (Créer personnalisé)**.

2. Saisissez un **Name (Nom)** descriptif pour votre Action (par exemple, `changer l’image des utilisateurs`, sélectionnez le déclencheur `Login/Post Login` (connexion/post-connexion), car vous allez ajouter l’Action au flux de connexion, puis sélectionnez **Create (Créer)**.

3. Repérez l’éditeur de code des actions, copiez le code JavaScript suivant dans celui-ci, puis sélectionnez **Save Draft (Enregistrer le brouillon)**  pour enregistrer vos modifications :

   ```lines theme={null}
   exports.onExecutePostLogin = async (event, api) => {
     const { picture } = event.user.user_metadata;
     if (picture) {
       // Return the persisted user_metadata.picture in the ID token
       api.idToken.setCustomClaim("picture", picture)
     }
   };
   ```

4. Dans la barre latérale de l’éditeur de code des actions, sélectionnez Test (icône de lecture), puis sélectionnez **Run (Exécuter)** pour [tester votre code](/docs/fr-ca/customize/actions/test-actions).

5. Lorsque vous êtes prêt à lancer l’action, sélectionnez **Deploy (Déployer)**.

Enfin, ajoutez l’Action que vous avez créée dans le [flux de connexion](https://manage.auth0.com/#/actions/flows/login/). Pour savoir comment attacher des actions à des flux, lisez la section « Attacher l’action à un flux » dans [Écriture de votre première action](/docs/fr-ca/customize/actions/write-your-first-action).

## Modifier l’image par défaut pour tous les utilisateurs

Pour changer l’image par défaut de tous les utilisateurs qui n’ont pas défini d’image de profil, vous pouvez utiliser une action. Par exemple :

```javascript lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  const DEFAULT_PROFILE_IMAGE = '{yourDefaultImageUrl}';
  api.idToken.setCustomClaim("picture", {defaultProfileImage});
};
```

Dans cette Action, l’image personnalisée est renvoyée dans le jeton d’ID et remplace toute propriété d’ `image` pouvant provenir d’une connexion à un fournisseur d’identité externe, tel que Google.

## Limites

Le magasin de données Auth0 a une capacité limitée et pour éviter que les données de votre application ne dépassent les limites, nous vous recommandons d’utiliser une base de données externe pour stocker les images des utilisateurs. Cela vous permet de conserver un magasin de données Auth0 restreint et d’utiliser une base de données externe plus efficace pour contenir les données supplémentaires. Pour en savoir plus, consultez [Stockage des données utilisateur](/docs/fr-ca/secure/security-guidance/data-security/user-data-storage).

## En savoir plus

* [Structure du profil utilisateur](/docs/fr-ca/manage-users/user-accounts/user-profiles/user-profile-structure)
* [Attributs racine du profil utilisateur](/docs/fr-ca/manage-users/user-accounts/user-profiles/root-attributes)
* [Comprendre le fonctionnement des métadonnées dans les profils utilisateurs](/docs/fr-ca/manage-users/user-accounts/metadata)
* [Gérer les métadonnées à l’aide de Management API](/docs/fr-ca/manage-users/user-accounts/metadata/manage-metadata-api)
* [Gérer les métadonnées avec des règles](/docs/fr-ca/manage-users/user-accounts/metadata/manage-metadata-rules)
* [Importation d’utilisateurs par lot](/docs/fr-ca/manage-users/user-migration/bulk-user-imports)
