> ## 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.

> Describe las plantillas de script de acción de base de datos personalizadas para la búsqueda de usuarios.

# Plantillas de script de Get User

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](/es/docs/manage-users/user-migration/configure-automatic-migration-from-your-database) 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

<div id="get-user-function">
  ## Función `getUser`
</div>

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.

<div id="definition">
  ### Definición
</div>

La función `getUser` recibe dos parámetros y devuelve una función `callback`:

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

| Parámetro  | Tipo     | Descripción                                                     |
| ---------- | -------- | --------------------------------------------------------------- |
| `email`    | String   | La dirección de correo electrónico del usuario.                 |
| `callback` | Function | Se 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](#language-specific-script-examples).

```javascript lines expandable theme={null}
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);
      }
    }
  });
}
```

<div id="callback-function">
  ## Función de callback
</div>

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

<div id="definition">
  ### Definición
</div>

La función `callback` acepta hasta dos parámetros y devuelve otra función:

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

| Parámetro | Tipo   | Obligatorio | Descripción                                |
| --------- | ------ | ----------- | ------------------------------------------ |
| `error`   | Object | Obligatorio | Contiene los datos del error.              |
| `profile` | Object | Opcional    | Contiene los datos del perfil del usuario. |

<div id="return-the-user-profile-user-found">
  ### Devuelve el perfil del usuario (usuario encontrado)
</div>

<Warning>
  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.
</Warning>

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](/es/docs/manage-users/user-accounts/user-profiles/normalized-user-profile-schema). Además de los campos estándar, puedes incluir los campos `user_metadata`, `app_metadata` y `mfa_factors`.

<div id="example">
  #### Ejemplo
</div>

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

<div id="return-no-user-profile-user-not-found">
  ### No devuelva ningún perfil de usuario (usuario no encontrado)
</div>

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

<div id="example">
  #### Ejemplo
</div>

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

<div id="return-an-error">
  ### Devolver un error
</div>

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](/es/docs/authenticate/database-connections/custom-db/error-handling).

<div id="example">
  #### Ejemplo
</div>

```js lines theme={null}
return callback(new Error("My custom error message."));
```

<div id="language-specific-script-examples">
  ## Ejemplos de scripts específicos por lenguaje
</div>

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

* [JavaScript](#javascript)
* [Proveedor de membresía de ASP.NET (MVC3 - Universal Providers)](#asp-net-membership-provider-mvc3-universal-providers-)
* [Proveedor de membresía de ASP.NET (MVC4 - Simple Membership)](#asp-net-membership-provider-mvc4-simple-membership-)
* [MongoDB](#mongodb)
* [MySQL](#mysql)
* [PostgreSQL](#postgresql)
* [SQL Server](#sql-server)
* [Base de datos SQL de Windows Azure](#windows-azure-sql-database)
* [Axios](#axios)
* [Stormpath](#stormpath)

<div id="javascript">
  ### JavaScript
</div>

```javascript lines theme={null}
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));
}
```

<div id="aspnet-membership-provider-mvc3-universal-providers">
  ### Proveedor de membresía de ASP.NET (MVC3 - Universal Providers)
</div>

```javascript lines expandable theme={null}
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);
  });
}
```

<div id="aspnet-membership-provider-mvc4-simple-membership">
  ### Proveedor de membresía de ASP.NET (MVC4 - Simple Membership)
</div>

```javascript lines expandable theme={null}
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);
  });
}
```

<div id="mongodb">
  ### MongoDB
</div>

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

<div id="mysql">
  ### MySQL
</div>

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

<div id="postgresql">
  ### PostgreSQL
</div>

```javascript lines theme={null}
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
      });
    });
  });
}
```

<div id="sql-server">
  ### SQL Server
</div>

```javascript lines expandable theme={null}
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);
  });
}
```

<div id="windows-azure-sql-database">
  ### Base de datos SQL de Windows Azure
</div>

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

<div id="axios">
  ### Axios
</div>

```js lines expandable theme={null}
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));
  }
}
```

<div id="stormpath">
  ### Stormpath
</div>

```javascript lines expandable theme={null}
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
    });
  });
}
```

<div id="learn-more">
  ## Más información
</div>

* [Plantillas de scripts para cambiar la contraseña](/es/docs/authenticate/database-connections/custom-db/templates/change-password)
* [Plantillas de scripts de creación](/es/docs/authenticate/database-connections/custom-db/templates/create)
* [Plantillas de scripts de eliminación](/es/docs/authenticate/database-connections/custom-db/templates/delete)
* [Plantillas de scripts de inicio de sesión](/es/docs/authenticate/database-connections/custom-db/templates/login)
* [Plantillas de scripts de verificación](/es/docs/authenticate/database-connections/custom-db/templates/verify)
* [Plantilla de script para cambiar el correo electrónico](/es/docs/authenticate/database-connections/custom-db/templates/change-email)
