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

# Scripts et modèles d’actions de base de données Get User

> Le script Get User s’exécute lorsqu’Auth0 doit déterminer si un utilisateur existe ou non.

Le script Get User met en œuvre la fonction exécutée pour déterminer si un utilisateur existe actuellement. Nous vous recommandons de nommer cette fonction `getUser`.

Ce script est requis pour la [migration automatique vers Auth0](/docs/fr-ca/manage-users/user-migration/configure-automatic-migration-from-your-database); il peut également être requis sous certaines conditions lorsque la migration n’est pas activée, en fonction des opérations configurées pour la connexion. Auth0 recommande vivement que le `user_id` que vous renvoyez dans le profil utilisateur soit permanent et cohérent : pour un utilisateur donné, le script Get User doit renvoyer le même `user_id` à chaque exécution. Consultez [Renvoyer un user\_id cohérent](#return-a-consistent-user-id) pour plus de détails.

Lorsque l’option **Importer des utilisateurs vers Auth0** est activée, le script Get User s’exécute lorsqu’un utilisateur tente de s’inscrire, afin de vérifier si cet utilisateur existe déjà dans le magasin d’utilisateurs externe.

Le script Get User s’exécute également lorsqu’un utilisateur tente de :

* Modifier son adresse courriel (script [Change Email](/docs/fr-ca/authenticate/database-connections/custom-db/templates/change-email))
* Se connecter (script [Login](/docs/fr-ca/authenticate/database-connections/custom-db/templates/login))
* Modifier son mot de passe (script [Change Password](/docs/fr-ca/authenticate/database-connections/custom-db/templates/change-password))

Lorsque l’option **Importer des utilisateurs vers Auth0** est désactivée, le script Get User s’exécute lorsqu’un utilisateur tente de s’inscrire afin de vérifier s’il figure déjà dans le magasin d’utilisateurs externe. Si un utilisateur figure déjà dans ce magasin, le script Create n'est pas exécuté.

Le script Get User s’exécute également lorsqu’un utilisateur tente de :

* S’inscrire (script [Create](/docs/fr-ca/authenticate/database-connections/custom-db/templates/create))
* Modifier son adresse courriel (script [Change Email](/docs/fr-ca/authenticate/database-connections/custom-db/templates/change-email))
* Modifier ou réinitialiser son mot de passe (script [Change Password](/docs/fr-ca/authenticate/database-connections/custom-db/templates/change-password))

## Fonction Get User

La fonction `getUser` devrait :

* Envoyer l’identificateur de l’utilisateur à l’API de la base de données externe.
* Renvoyer les données de profil de l’utilisateur si celui-ci a été trouvé.
* Renvoyer une erreur si un problème est survenu lors de la vérification de l’existence ou non de l’utilisateur.

### Définition

La fonction `getUser` accepte deux paramètres et renvoie une fonction `callback` :

```js lines theme={null}
getUser(email, callback): function
```

| Paramètre  | Type     | Description                                                                                  |
| ---------- | -------- | -------------------------------------------------------------------------------------------- |
| `email`    | Chaîne   | L’adresse courriel de l’utilisateur.                                                         |
| `callback` | Fonction | Permet de transmettre les erreurs ou les données de profil à travers la chaîne de traitement |

Voici un exemple en pseudo-JavaScript illustrant comment vous pourriez implémenter la fonction `getUser` :

```javascript lines expandable theme={null}
function getUser(email, callback) {
  // Envoyer l’identificateur de l’utilisateur à l’API de la base de données externe
  let options = {
    url: "https://example.com/api/search-users",
    body: {
      email: email
    }
  };

  send(options, (err, profileData) => {
    // Renvoyer une erreur dans la fonction de callback si la recherche de l’utilisateur a échoué
    if (err) {
      return callback(new Error(« Impossible de déterminer si l’utilisateur existe ou non. »));
    } else {
      // Renvoyer null dans la fonction de callback si l’utilisateur n’a pas été trouvé, renvoyer les données de profil dans la fonction de callback si l’utilisateur a été trouvé
      if (!profileData) {
        return callback(null);
      } else {
        let profile = {
          email: profileData.email,
          user_id: profileData.userId
        };

        return callback(null, profile);
      }
    }
  });
}
```

## Fonction de callback

La fonction de `callback` sert à transmettre les données du profil utilisateur ou les données d’erreur à travers la chaîne de traitement.

### Définition

La fonction de `callback` accepte jusqu’à deux paramètres et renvoie une fonction :

```js lines theme={null}
callback(error[,profile]): function
```

| Paramètre | Type  | Obligatoire | Description                                 |
| --------- | ----- | ----------- | ------------------------------------------- |
| `error`   | Objet | Obligatoire | Contient les données d'erreur.              |
| `profile` | Objet | Facultatif  | Contient les données du profil utilisateur. |

### Renvoyer le profil utilisateur (utilisateur trouvé)

<Warning>
  Les données de profil renvoyées par le script Get User pour un utilisateur doivent correspondre aux données de profil renvoyées par le script Login.
</Warning>

Si l’utilisateur est trouvé, transmettez une valeur `null` au paramètre `error`, puis transmettez les données de profil utilisateur au paramètre `profile` sous [forme normalisée](/docs/fr-ca/manage-users/user-accounts/user-profiles/normalized-user-profile-schema) :

```js lines theme={null}
return callback(null, {
    username: "username",
    user_id: "my-custom-db|username@domain.com",
    email: "username@domain.com",
    email_verified: false,
    user_metadata: {
        language: "en"
    },
    app_metadata: {
        plan: "full"
    },
    mfa_factors: [
      {
        phone: {
          value: "+15551234567"
        }
      },
    ]
});
```

En plus des champs standard, vous pouvez inclure les champs `user_metadata`, `app_metadata` et `mfa_factors`.

### Renvoyer un user\_id cohérent

Auth0 utilise le `user_id` renvoyé par le script Get User pour identifier l’utilisateur au sein de votre locataire. Pour un utilisateur donné, cette valeur doit être **cohérente** : le script Get User doit renvoyer le même `user_id` à chaque fois qu’il est exécuté pour cet utilisateur. Déterminez l’`user_id` à partir d’une propriété stable et permanente de votre enregistrement source (telle que la clé primaire de la base de données), et non à partir d’une valeur susceptible de varier d’une exécution à l’autre.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Renvoyer un `user_id` incohérent peut entraîner la création d’utilisateurs en double ou orphelins, et peut perturber les flux qui reposent sur la stabilité de cet identificateur.
</Callout>

Obtenez l'`user_id` à partir d'une propriété stable de l'enregistrement source, de sorte que le même utilisateur corresponde toujours à la même valeur.

```js lines theme={null}
return callback(null, {
    // `user.id` est la clé primaire immuable de votre base de données
    user_id: "my-custom-db|" + user.id,
    email: user.email,
    email_verified: user.email_verified
});
```

Ne générez pas un `user_id` nouveau ou aléatoire à chaque appel. Par exemple, en renvoyant un UUID fraîchement généré. Cela produit un identificateur différent à chaque exécution du script pour un même utilisateur.

```js lines theme={null}
const { v4: uuidv4 } = require("uuid");

return callback(null, {
    // Anti-modèle : une nouvelle valeur est générée à chaque exécution, ce qu'Auth0 considère à chaque fois comme un nouveau utilisateur
    user_id: uuidv4(),
    email: user.email,
    email_verified: user.email_verified
});
```

### Ne pas renvoyer de profil utilisateur (utilisateur introuvable)

Si l’utilisateur est introuvable, attribuez la valeur `null` au paramètre `error` et omettez le paramètre `profile` :

```js lines theme={null}
return callback(null);
```

### Renvoyer une erreur

En cas d’erreur, transmettez les données d'erreur au paramètre `error` en y incluant les informations pertinentes sur la nature du problème :

```js lines theme={null}
return callback(new Error(« Mon message d’erreur personnalisé. »));
```

Pour plus d'informations, consultez [Dépannage des connexions de bases de données personnalisées](/docs/fr-ca/authenticate/database-connections/custom-db/error-handling).

## Exemples de scripts propres à chaque langue

Auth0 propose des exemples de scripts destinés à être utilisés avec les langues et les technologies suivantes :

<CodeGroup>
  ```javascript Javascript lines theme={null}
  function getByEmail(email, callback) {
    // Ce script doit récupérer un profil utilisateur à partir de votre base de données existante,
    // sans authentifier l’utilisateur.
    // Il sert à vérifier si un utilisateur existe avant d’exécuter des flux qui ne
    // nécessitent pas d’authentification (inscription et réinitialisation du mot de passe).
    //
    // Il y a trois façons dont ce script peut se terminer :
    // 1. Un utilisateur a bien été trouvé. Le profil doit respecter le
    // format suivant : https://auth0.com/docs/users/normalized/auth0/normalized-user-profile-schema.
    //     callback(null, profile);
    // 2. Aucun utilisateur n’a été trouvé
    //     callback(null);
    // 3. Une erreur s’est produite lors de la tentative d’accès à votre base de données :
    //     callback(new Error("mon message d’erreur"));
    const msg = 'Please implement the Get User script for this database connection ' +
      'at https://manage.auth0.com/#/connections/database';
    return callback(new Error(msg));
  }
  ```

  ```javascript ASP.NET MVC3 lines expandable theme={null}
  // Pour ASP.NET Membership Provider (MVC3 - Universal Providers)
  function getByEmail(email, callback) {
    const sqlserver = require('tedious@1.11.0');
    const Connection = sqlserver.Connection;
    const Request = sqlserver.Request;
    const TYPES = sqlserver.TYPES;
    const connection = new Connection({
      userName: 'the username',
      password: 'the password',
      server: 'the server',
      options: {
        database: 'the db name',
        encrypt: true // pour Windows Azure
      }
    });
    connection.on('debug', function(text) {
      // si vous rencontrez des problèmes de connexion, supprimez le commentaire de cette ligne pour obtenir des informations plus détaillées
      //console.log(text);
    }).on('errorMessage', function(text) {
      // cela affichera toute erreur lors de la connexion à la base de données SQL ou avec les instructions SQL
      console.log(JSON.stringify(text));
    });
    connection.on('connect', function(err) {
      if (err) return callback(err);
      var user = {};
      const query =
        'SELECT Memberships.UserId, Email, Users.UserName ' +
        'FROM Memberships INNER JOIN Users ' +
        'ON Users.UserId = Memberships.UserId ' +
        'WHERE Memberships.Email = @Username OR Users.UserName = @Username';
      const getMembershipQuery = new Request(query, function(err, rowCount) {
        if (err) return callback(err);
        if (rowCount < 1) return callback();
        callback(null, user);
      });
      getMembershipQuery.addParameter('Username', TYPES.VarChar, email);
      getMembershipQuery.on('row', function(fields) {
        user = {
          user_id: fields.UserId.value,
          nickname: fields.UserName.value,
          email: fields.Email.value
        };
      });
      connection.execSql(getMembershipQuery);
    });
  }
  ```

  ```javascript ASP.NET MVC4 lines expandable theme={null}
  // Pour ASP.NET Membership Provider (MVC4 - Simple Membership)
  function getByEmail(email, callback) {
    const sqlserver = require('tedious@1.11.0');
    const Connection = sqlserver.Connection;
    const Request = sqlserver.Request;
    const TYPES = sqlserver.TYPES;
    const connection = new Connection({
      userName: 'the username',
      password: 'the password',
      server: 'the server',
      options: {
        database: 'the db name',
        encrypt: true // pour Windows Azure
      }
    });
    connection.on('debug', function(text) {
      // si vous avez des problèmes de connexion, décommentez ceci pour obtenir des informations plus détaillées
      //console.log(text);
    }).on('errorMessage', function(text) {
      // cela affichera toute erreur lors de la connexion à la base de données SQL ou avec les instructions SQL
      console.log(JSON.stringify(text));
    });
    connection.on('connect', function(err) {
      if (err) return callback(err);
      var user = {};
      const query =
        'SELECT webpages_Membership.UserId, UserName, UserProfile.UserName from webpages_Membership ' +
        'INNER JOIN UserProfile ON UserProfile.UserId = webpages_Membership.UserId ' +
        'WHERE UserProfile.UserName = @Username';
      const getMembershipQuery = new Request(query, function (err, rowCount) {
        if (err) return callback(err);
        if (rowCount < 1) return callback();
        callback(null, user);
      });
      getMembershipQuery.addParameter('Username', TYPES.VarChar, email);
      getMembershipQuery.on('row', function (fields) {
        user = {
          user_id: fields.UserId.value,
          nickname: fields.UserName.value,
          email: fields.UserName.value
        };
      });
      connection.execSql(getMembershipQuery);
    });
  }
  ```

  ```javascript MongoDB lines theme={null}
  function getByEmail(email, callback) {
    const MongoClient = require('mongodb@5.1.0').MongoClient;
    const client = new MongoClient('mongodb://user:pass@mymongoserver.com');
    client.connect(function (err) {
      if (err) return callback(err);
      const db = client.db('db-name');
      const users = db.collection('users');
      users.findOne({ email: email }, function (err, user) {
        client.close();
        if (err) return callback(err);
        if (!user) return callback(null, null);
        return callback(null, {
          user_id: user._id.toString(),
          nickname: user.nickname,
          email: user.email
        });
      });
    });
  }
  ```

  ```javascript MySQL lines theme={null}
  function getByEmail(email, callback) {
    const mysql = require('mysql');
    const connection = mysql({
      host: 'localhost',
      user: 'me',
      password: 'secret',
      database: 'mydb'
    });
    connection.connect();
    const query = 'SELECT id, nickname, email FROM users WHERE email = ?';
    connection.query(query, [ email ], function(err, results) {
      if (err || results.length === 0) return callback(err || null);
      const user = results[0];
      callback(null, {
        user_id: user.id.toString(),
        nickname: user.nickname,
        email: user.email
      });
    });
  }
  ```

  ```javascript PostgreSQL lines theme={null}
  function loginByEmail(email, callback) {
    //cet exemple utilise la bibliothèque "pg"
    //plus d’informations ici : https://github.com/brianc/node-postgres
    const postgres = require('pg');
    const conString = 'postgres://user:pass@localhost/mydb';
    postgres.connect(conString, function (err, client, done) {
      if (err) return callback(err);
      const query = 'SELECT id, nickname, email FROM users WHERE email = $1';
      client.query(query, [email], function (err, result) {
        // REMARQUE : toujours appeler `done()` ici pour fermer
        // la connexion à la base de données
        done();
        if (err || result.rows.length === 0) return callback(err);
        const user = result.rows[0];
        return callback(null, {
          user_id: user.id,
          nickname: user.nickname,
          email: user.email
        });
      });
    });
  }
  ```

  ```javascript SQL Server lines expandable theme={null}
  function getByEmail(email, callback) {
    //cet exemple utilise la bibliothèque "tedious"
    //plus d’informations ici : http://pekim.github.io/tedious/index.html
    const sqlserver = require('tedious@1.11.0');
    const Connection = sqlserver.Connection;
    const Request = sqlserver.Request;
    const TYPES = sqlserver.TYPES;
    const connection = new Connection({
      userName:  'test',
      password:  'test',
      server:    'localhost',
      options:  {
        database: 'mydb'
      }
    });
    const query = 'SELECT Id, Nickname, Email FROM dbo.Users WHERE Email = @Email';
    connection.on('debug', function (text) {
      console.log(text);
    }).on('errorMessage', function (text) {
      console.log(JSON.stringify(text, null, 2));
    }).on('infoMessage', function (text) {
      console.log(JSON.stringify(text, null, 2));
    });
    connection.on('connect', function (err) {
      if (err) return callback(err);
      const request = new Request(query, function (err, rowCount, rows) {
        if (err) return callback(err);
        callback(null, {
          user_id: rows[0][0].value,
          nickname: rows[0][1].value,
          email: rows[0][2].value
        });
      });
      request.addParameter('Email', TYPES.VarChar, email);
      connection.execSql(request);
    });
  }
  ```

  ```javascript Azure SQL Database lines theme={null}
  function getByEmail (name, callback) {
    var profile = {
      user_id:     "103547991597142817347",
      nickname:    "johnfoo",
      email:       "johnfoo@gmail.com",
      name:        "John Foo",
      given_name:  "John",
      family_name: "Foo"
    };
    callback(null, profile);
  }
  ```

  ```js Axios lines expandable theme={null}
  async function getUserAsync(email, callback) {
    //doit être mis à jour à mesure que de nouvelles versions d’axios sont publiées (https://auth0-extensions.github.io/canirequire/#axios)
    const axios = require("axios@0.22.0");

    let response;

    try {
      response = await axios.post(
        //stocker l’URL de l’API dans les paramètres de connexion pour mieux prendre en charge les environnements SDLC
        configuration.baseAPIUrl + "/getUser",
        //identifiants de l’utilisateur transmis dans le corps de la requête
        {
          email: email,
        },
        {
          timeout: 10000, //terminer l’appel de façon sécurisée si la requête expire, afin que le script puisse effectuer le rappel nécessaire
          headers: {
            //sécurisation de l’appel API avec une apiKey stockée dans les paramètres de connexion.
            //approche rapide et simple, cependant l’utilisation de jetons de communication entre machines est plus sécurisée, car
            // un secret ne doit pas être partagé entre le client et l’API.
            "x-api-key": configuration.apiKey,
          },
        }
      );
    } catch (e) {
      if (e.response.status === 404) {
        //En supposant que l’API renvoie un code 404 lorsqu’aucun utilisateur correspondant à l’adresse de courriel ou au nom d’utilisateur indiqué n’est trouvé
        return callback(null, null);
      }
      //rappel pour tout autre type d’erreur
      return callback(new Error(e.message));
    }

    try {
      let user = response.data;

      //si vous utilisez plusieurs connexions personnalisées de base de données dans votre locataire, préfixez le
      //user_id avec une clé propre à la connexion, p. ex. : "connName|" + user.user_id
      //cela garantit des identifiants utilisateur uniques pour toutes les connexions de base de données
      return callback(null, {
        user_id: user.user_id,
        email: user.email,
      });
    } catch (e) {
      return callback(new Error(e.message));
    }
  }
  ```

  ```javascript Stormpath lines expandable theme={null}
  function getByEmail(email, callback) {
    // Remplacer {yourStormpathClientId} par votre identifiant Stormpath
    var url = 'https://api.stormpath.com/v1/applications/{yourStormpathClientId}/accounts';
    // Ajouter votre identifiant client et votre secret d’API Stormpath
    var apiCredentials = {
      user : '{yourStormpathApiId}',
      password: '{yourStormpathApiSecret}'
    };
    // Effectuer une requête GET pour trouver un utilisateur par courriel
    request({
      url: url,
      method: 'GET',
      auth: apiCredentials,
      qs: { q: email },
      json: true
    }, function (error, response, body) {
      if (response.statusCode !== 200) return callback();
      var user = body.items[0];
      if (!user) return callback();
      var id = user.href.replace('https://api.stormpath.com/v1/accounts/', '');
      return callback(null, {
        user_id: id,
        username: user.username,
        email: user.email,
        email_verified: true
        // Ajouter tout champ supplémentaire que vous souhaitez transférer depuis Stormpath
      });
    });
  }
  ```
</CodeGroup>
