Passer au contenu principal
Le script Get User implémente 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 et, selon les opérations configurées pour la connexion, peut aussi être requis pour l’authentification héritée. Auth0 vous recommande de définir un user_id permanent dans le profil utilisateur renvoyé afin d’éviter la création d’utilisateurs en double. Si la migration automatique est configurée pour la connexion et que le profil utilisateur n’a pas encore été créé, le script est exécuté chaque fois que l’une des opérations suivantes se produit :
  • Changement de courriel
  • Inscription
  • Réinitialisation du mot de passe
Si l’authentification héritée est configurée pour la connexion, le script est exécuté chaque fois que l’une des opérations suivantes se produit :
  • Création d’utilisateur
  • Changement de courriel
  • Changement de mot de passe
  • Réinitialisation du mot de passe

Fonction getUser

La fonction getUser doit :
  • Envoyer l’identifiant de l’utilisateur à l’API de la base de données externe.
  • Retourner les données de profil de l’utilisateur si celui-ci a été trouvé.
  • Retourner une erreur s’il y a eu un problème pour déterminer si l’utilisateur existe ou non.

Définition

La fonction getUser prend deux paramètres et retourne une fonction callback :
getUser(email, callback): function
ParamètreTypeDescription
emailStringL’adresse courriel de l’utilisateur.
callbackFunctionSert à transmettre les erreurs ou les données de profil dans le pipeline

Exemple

Voici un exemple en pseudo-JavaScript montrant comment vous pourriez implémenter la fonction getUser. Pour des exemples propres à chaque langage, consultez Exemples de scripts par langage.
function getUser(email, callback) {
  // Envoyer l'identifiant de l'utilisateur à l'API de base de données externe
  let options = {
    url: "https://example.com/api/search-users",
    body: {
      email: email
    }
  };

  send(options, (err, profileData) => {
    // Retourner une erreur dans le rappel s'il y a eu un problème lors de la recherche de l'utilisateur
    if (err) {
      return callback(new Error("Could not determine if user exists or not."));
    } else {
      // Retourner null dans le rappel si l'utilisateur n'a pas été trouvé, retourner les données de profil dans le rappel 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 rappel

La fonction callback sert à transmettre les données de profil de l’utilisateur ou les données d’erreur dans le pipeline.

Définition

La fonction callback accepte un maximum de deux paramètres et renvoie une fonction :
callback(error[,profile]): function
ParamètreTypeObligatoireDescription
errorObjectObligatoireContient les données d’erreur.
profileObjectFacultatifContient les données du profil de l’utilisateur.

Retourner le profil de l’utilisateur (utilisateur trouvé)

Les données de profil renvoyées par le script Get User pour un utilisateur doivent correspondre à celles renvoyées par le script Login.
Si l’utilisateur est trouvé, transmettez la valeur null au paramètre error, puis transmettez les données de profil de l’utilisateur au paramètre profile sous forme normalisée. En plus des champs standard, vous pouvez inclure les champs user_metadata, app_metadata et mfa_factors.

Exemple

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"
        }
      },
    ]
});

Ne renvoyez aucun profil d’utilisateur (utilisateur introuvable)

Si l’utilisateur est introuvable, transmettez une valeur null au paramètre error et omettez le paramètre profile.

Exemple

return callback(null);

Retourner une erreur

Si une erreur se produit, transmettez les données d’erreur au paramètre error avec des renseignements pertinents sur l’erreur. Pour en savoir plus, consultez Résoudre les problèmes liés aux bases de données personnalisées.

Exemple

return callback(new Error("My custom error message."));

Exemples de scripts par langage

Auth0 fournit des exemples de scripts pour les langages et technologies suivants :

JavaScript

function getByEmail(email, callback) {
  // Ce script doit récupérer un profil utilisateur depuis 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).
  //
  // Ce script peut se terminer de trois façons :
  // 1. Un utilisateur a été trouvé avec succès. Le profil doit être au 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("my error message"));
  const msg = 'Please implement the Get User script for this database connection ' +
    'at https://manage.auth0.com/#/connections/database';
  return callback(new Error(msg));
}

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 // for Windows Azure
    }
  });
  connection.on('debug', function(text) {
    // si vous avez des problèmes de connexion, décommentez cette ligne pour obtenir plus de détails
    //console.log(text);
  }).on('errorMessage', function(text) {
    // ceci affichera toutes les erreurs lors de la connexion à la base de données SQL ou dans 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);
  });
}

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) {
    // affiche les erreurs lors de la connexion à la base de données SQL ou lors de l'exécution des 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);
  });
}

MongoDB

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

MySQL

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

PostgreSQL

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 : appelez toujours `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
      });
    });
  });
}

SQL Server

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

Windows Azure SQL Database

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

Axios

async function getUserAsync(email, callback) {
  //à mettre à jour lorsque de nouvelles versions d'axios sont disponibles (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 proprement si la requête expire afin que le script puisse effectuer le rappel nécessaire
        headers: {
          //sécurisation de l'appel API avec l'apiKey stockée dans les paramètres de connexion.
          //approche simple et rapide, mais l'utilisation de jetons M2M est plus sécurisée car
          // un secret ne doit pas être partagé entre l'application et l'API.
          "x-api-key": configuration.apiKey,
        },
      }
    );
  } catch (e) {
    if (e.response.status === 404) {
      //supposant que l'API retourne 404 lorsqu'aucun utilisateur avec le courriel/nom d'utilisateur spécifié 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 de base de données personnalisées dans votre locataire, préfixez le
    //user_id avec une clé propre à la connexion, ex. : "connName|" + user.user_id
    //cela garantit des identifiants d'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));
  }
}

Stormpath

function getByEmail(email, callback) {
  // Remplacez {yourStormpathClientId} par votre ID Stormpath
  var url = 'https://api.stormpath.com/v1/applications/{yourStormpathClientId}/accounts';
  // Ajoutez votre ID client et votre secret d'API Stormpath
  var apiCredentials = {
    user : '{yourStormpathApiId}',
    password: '{yourStormpathApiSecret}'
  };
  // Effectuez 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
      // Ajoutez tout champ supplémentaire que vous souhaitez transférer depuis Stormpath
    });
  });
}

En savoir plus