Saltar al contenido principal
El script Get User implementa la función que se ejecuta para determinar si un usuario existe actualmente. Recomendamos llamar a esta función getUser. Este script es obligatorio para la migración automática y, de forma condicional, para la autenticación heredada, según las operaciones configuradas para la conexión. Auth0 recomienda establecer un user_id permanente en el perfil de usuario devuelto para evitar la creación de usuarios duplicados. Si la migración automática está configurada para la conexión y el perfil de usuario aún no se ha creado, el script se ejecuta cada vez que se realiza una de las siguientes operaciones:
  • Cambiar correo electrónico
  • Registrarse
  • Restablecer la contraseña
Si la autenticación heredada está configurada para la conexión, el script se ejecuta cada vez que se realiza una de las siguientes operaciones:
  • Crear usuario
  • Cambiar correo electrónico
  • Cambiar contraseña
  • Restablecer la contraseña

Función getUser

La función getUser debe:
  • Enviar el identificador del usuario a la API de la base de datos externa.
  • Devolver los datos de perfil del usuario si se encuentra.
  • Devolver un error si hubo algún problema para determinar si el usuario existe o no.

Definición

La función getUser recibe dos parámetros y devuelve una función callback:
getUser(email, callback): function
ParámetroTipoDescripción
emailStringLa dirección de correo electrónico del usuario.
callbackFunctionSe usa para pasar errores o datos del perfil a través del flujo

Ejemplo

Este es un ejemplo en seudo-JavaScript de cómo podría implementar la función getUser. Para ver ejemplos específicos de cada lenguaje, consulte Ejemplos de scripts específicos por lenguaje.
function getUser(email, callback) {
  // Enviar el identificador de usuario a la API de base de datos externa
  let options = {
    url: "https://example.com/api/search-users",
    body: {
      email: email
    }
  };

  send(options, (err, profileData) => {
    // Devolver error en el callback si hubo un problema al encontrar el usuario
    if (err) {
      return callback(new Error("Could not determine if user exists or not."));
    } else {
      // Devolver null en el callback si no se encontró el usuario; devolver los datos del perfil en el callback si se encontró el usuario
      if (!profileData) {
        return callback(null);
      } else {
        let profile = {
          email: profileData.email,
          user_id: profileData.userId
        };

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

Función de callback

La función callback se utiliza para pasar datos del perfil del usuario o datos de error a través del flujo.

Definición

La función callback acepta hasta dos parámetros y devuelve otra función:
callback(error[,profile]): function
ParámetroTipoObligatorioDescripción
errorObjectObligatorioContiene los datos del error.
profileObjectOpcionalContiene los datos del perfil del usuario.

Devuelve el perfil del usuario (usuario encontrado)

Los datos del perfil que devuelve el script Get User para un usuario deben coincidir con los datos del perfil que devuelve el script Login.
Si se encuentra el usuario, pasa un valor null al parámetro error y los datos del perfil del usuario al parámetro profile en formato normalizado. Además de los campos estándar, puedes incluir los campos user_metadata, app_metadata y mfa_factors.

Ejemplo

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

No devuelva ningún perfil de usuario (usuario no encontrado)

Si no se encuentra al usuario, pase un valor null al parámetro error y omita el parámetro profile.

Ejemplo

return callback(null);

Devolver un error

Si se produce un error, pasa los datos del error al parámetro error con información relevante sobre lo que falló. Para obtener más información, consulta Solucionar problemas de bases de datos personalizadas.

Ejemplo

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

Ejemplos de scripts específicos por lenguaje

Auth0 proporciona scripts de ejemplo para usar con los siguientes lenguajes/tecnologías:

JavaScript

function getByEmail(email, callback) {
  // Este script debe recuperar un perfil de usuario de su base de datos existente,
  // sin autenticar al usuario.
  // Se utiliza para verificar si un usuario existe antes de ejecutar flujos que no
  // requieren autenticación (registro y restablecimiento de contraseña).
  //
  // Hay tres maneras en que este script puede finalizar:
  // 1. Se encontró un usuario correctamente. El perfil debe tener el siguiente
  // formato: https://auth0.com/docs/users/normalized/auth0/normalized-user-profile-schema.
  //     callback(null, profile);
  // 2. No se encontró ningún usuario
  //     callback(null);
  // 3. Algo salió mal al intentar conectarse a su base de datos:
  //     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));
}

Proveedor de membresía de ASP.NET (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 tienes problemas de conexión, descomenta esto para obtener información más detallada
    //console.log(text);
  }).on('errorMessage', function(text) {
    // esto mostrará cualquier error al conectarse a la base de datos SQL o con las sentencias 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);
  });
}

Proveedor de membresía de ASP.NET (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 // for Windows Azure
    }
  });
  connection.on('debug', function(text) {
    // si tienes problemas de conexión, descomenta esto para obtener información más detallada
    //console.log(text);
  }).on('errorMessage', function(text) {
    // esto mostrará cualquier error al conectarse a la base de datos SQL o con las sentencias 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) {
  //este ejemplo usa la librería "pg"
  //más información aquí: 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) {
      // NOTA: siempre llama a `done()` aquí para cerrar
      // la conexión a la base de datos
      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) {
  //este ejemplo usa la biblioteca "tedious"
  //más información aquí: 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);
  });
}

Base de datos SQL de Windows Azure

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) {
  //debe actualizarse cuando haya nuevas versiones de axios disponibles (https://auth0-extensions.github.io/canirequire/#axios)
  const axios = require("axios@0.22.0");

  let response;

  try {
    response = await axios.post(
      //almacene la URL de la API en la configuración de la conexión para un mejor soporte de entornos SDLC
      configuration.baseAPIUrl + "/getUser",
      //credenciales del usuario enviadas como cuerpo de la solicitud
      {
        email: email,
      },
      {
        timeout: 10000, //finaliza la llamada de forma controlada si la solicitud expira, para que el script pueda ejecutar el callback necesario
        headers: {
          //protege la llamada a la API con la apiKey almacenada en la configuración de la conexión.
          //es un enfoque rápido y sencillo, aunque usar tokens M2M es más seguro, ya que
          // un secreto no debe compartirse entre el cliente y la API.
          "x-api-key": configuration.apiKey,
        },
      }
    );
  } catch (e) {
    if (e.response.status === 404) {
      //se asume que la API devuelve 404 cuando no se encuentra ningún usuario con el correo electrónico/username especificado
      return callback(null, null);
    }
    //callback para cualquier otro tipo de error
    return callback(new Error(e.message));
  }

  try {
    let user = response.data;

    //si usa múltiples conexiones de base de datos personalizadas en su tenant, agregue como prefijo
    //al user_id una clave específica de la conexión, p. ej.: "connName|" + user.user_id
    //esto garantiza IDs de usuario únicos en todas las conexiones de base de datos
    return callback(null, {
      user_id: user.user_id,
      email: user.email,
    });
  } catch (e) {
    return callback(new Error(e.message));
  }
}

Stormpath

function getByEmail(email, callback) {
  // Reemplaza {yourStormpathClientId} con tu ID de Stormpath
  var url = 'https://api.stormpath.com/v1/applications/{yourStormpathClientId}/accounts';
  // Agrega tu ID de cliente y secreto de la API de Stormpath
  var apiCredentials = {
    user : '{yourStormpathApiId}',
    password: '{yourStormpathApiSecret}'
  };
  // Realiza una solicitud GET para encontrar un usuario por correo electrónico
  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
      // Agrega cualquier campo adicional que quieras migrar desde Stormpath
    });
  });
}

Más información