Overview
El proveedor de autenticación de función personalizada permite definir un flujo de autenticación personalizado utilizando una función sin servidor. Puede utilizar este proveedor para implementar su propio lógica de autenticación de usuario o integrar un sistema de autenticación externo.
Cuándo utilizar la autenticación de funciones personalizadas
La autenticación con funciones personalizadas es la forma más flexible de autenticación. Sin embargo, también requiere que usted mismo defina y configure manualmente el flujo de autenticación.
Antes de definir un proveedor de funciones personalizado, considere si puede utilizar uno de los proveedores de autenticación integrados.
Considera usar el proveedor de función personalizada en tu aplicación si:
You want to use an external authentication service that does not have a built-in provider. If the service uses JSON web tokens, consider creating a Custom JWT provider instead.
Desea personalizar el proceso de autenticación más allá de lo que ofrece un proveedor integrado. Por ejemplo, podría usar un servicio para enviar correos electrónicos de confirmación personalizados en lugar de los correos predeterminados del proveedor de correo electrónico/contraseña.
Importante
Atlas App Services no realiza ninguna validación de datos ni comprobaciones de autenticación para el proveedor de función personalizada.
Asegúrese de validar los datos entrantes y de que su sistema de autenticación realice las comprobaciones de autenticación adecuadas, como solicitar una contraseña, autenticación de dos factores, o un token de inicio de sesión único.
El siguiente diagrama muestra el proceso de inicio de sesión de una función personalizada:

La función de autenticación
La función de autenticación es una función JavaScript que contiene tu código personalizado de autenticación de usuario. Se ejecuta cada vez que un usuario inicia sesión a través del proveedor de función personalizada.
La función asigna los datos proporcionados al iniciar sesión, como el nombre de usuario y la contraseña o un token de acceso, a una cadena que identifica de forma única al usuario en su sistema de autenticación externo. Por ejemplo, podría usar los datos proporcionados para iniciar sesión en un servicio externo mediante HTTP o con un paquete de npm.
exports = async function (payload) { // 1. Parse the `payload` object, which holds data from the // FunctionCredential sent by the SDK. const { username, password } = payload; // 2. Create a new user or log in an existing user in the external // authentication service. // You can use a client library from npm const auth = require("fake-auth-service"); const user = await auth.login({ username, password }); // Or you can communicate directly over HTTP const userFromHttp = await context.http.post({ url: "https://example.com/auth/login", headers: { Authorization: ["Basic bmlja0BleGFtcGxlLmNvbTpQYTU1dzByZA=="], }, body: JSON.stringify({ username, password }), }); // 3. Return a unique identifier for the user. Typically this is the // user's ID in the external authentication system or the _id of a // stored MongoDB document that describes them. // // !!! This is NOT the user's internal account ID for your app !!! return user.id; };
Recibir una carga útil de credenciales personalizada
La payload El objeto pasado a la función contiene datos incluidos con la credencial del proveedor de la función personalizada en la aplicación cliente. La función acepta cualquier valor proporcionado por la aplicación cliente, por lo que los nombres y valores de los campos dependen de la implementación.
For examples of how to create a custom credential payload object using the Realm SDKs, refer to the documentation for each SDK:
Return an Authenticated User ID
Si la autenticación es correcta, la función debe devolver un identificador de cadena único para el usuario. Por ejemplo, podría devolver el valor del ID de usuario utilizado por su sistema de autenticación externo. Este es el ID externo del usuario, que el proveedor utiliza para asignar desde su sistema personalizado a las cuentas de usuario internas de su aplicación.
Importante
El ID externo del usuario no es el mismo que el ID interno de la cuenta, que se expone como el id campo de un objeto de usuario. Se accede al ID interno del usuario con %%user.id en expresiones, context.user.id en funciones y la User.id propiedad en los SDK.
If an existing user is already associated with the external ID, the provider logs that user in.
Si el proveedor no tiene registro de una identificación externa determinada, crea una nueva cuenta de usuario, agrega una identidad de proveedor de función personalizada y luego inicia sesión con el nuevo usuario.
El objeto de identidad para el proveedor de la función personalizada se almacena en el objeto de usuario y es similar a lo siguiente:
{ "id": "<Internal User Account ID>", "identities": [ { "providerType": "custom-function", "id": "<External User ID>", } ] }
Ejemplo
La función de autenticación debe devolver una identificación externa única como una cadena:
return "5f650356a8631da45dd4784c"
You can also return an object that contains the external ID as its id value:
return { "id": "5f650356a8631da45dd4784c" }
If you want to define a display name for the user, define it in the name field of the returned object:
return { "id": "5f650356a8631da45dd4784c", "name": "James Bond" }
Lanzar un error por autenticación fallida
Si el usuario proporciona credenciales no válidas o la función no logra autenticar al usuario por otro motivo, lanzar un error con un mensaje descriptivo. Esto devuelve un error 401 - Unauthorized con el mensaje adjunto al SDK.
const auth = require("some-external-auth-system"); try { const user = await auth.login(payload); return user.id; } catch (err) { throw new Error(`Authentication failed with reason: ${err.message}`); }
Configurar el proveedor de función personalizada
You can configure custom function authentication using any supported deployment method.
Habilitar el proveedor de funciones personalizadas
Para habilitar el proveedor:
Haga clic App Users en el menú de navegación de la izquierda.
Selecciona la pestaña Providers.
Haga clic en Custom Function Authentication.
En la pantalla de configuración del proveedor, cambie el interruptor Provider Enabled a On.

Define the Authentication Function
El proveedor utiliza una función normal para gestionar la autenticación. Esta función debe devolver una cadena de identificación externa única para identificar al usuario.
Para definir una nueva función de autenticación:
Haz clic en el desplegable Function y selecciona New Function.
Introduzca un nombre para la función. Este nombre debe ser único entre todas las funciones de la aplicación.
Define el código fuente en el editor de funciones.
Haga clic Save

Implementar la aplicación actualizada
Para que la autenticación de funciones personalizadas esté disponible para las aplicaciones cliente, implemente su aplicación.
Haga clic en Deploy en el menú de navegación de la izquierda
Busque el borrador en la tabla del historial de implementación y luego haga clic en Review & Deploy Changes.
Revise la diferencia de cambios y luego haga clic en Deploy.
Obtenga la última versión de su aplicación
Para extraer una copia local de la última versión de su aplicación, ejecute lo siguiente:
appservices pull --remote="<Your App ID>"
Tip
También puedes descargar una copia de los archivos de configuración de tu aplicación desde la pantalla Deploy > Export App en la Interfaz de usuario Realm.
Define the Authentication Function
El proveedor utiliza una función normal para gestionar la autenticación. Esta función debe devolver una cadena de identificación externa única para identificar al usuario.
Guarde el código de la función de autenticación en el functions directorio.
touch functions/handleCustomFunctionAuthentication.js
Add a Provider Configuration File
Para habilitar y configurar el proveedor de autenticación de función personalizada, defina un objeto de configuración para él /auth/providers.json en.
Las configuraciones del proveedor de funciones personalizadas tienen el siguiente formato:
{ "custom-function": { "name": "custom-function", "type": "custom-function", "config": { "authFunctionName": "<Authentication Function Name>" }, "disabled": false } }
Configure Custom User Data
Puedes asociar datos personalizados de una colección de MongoDB Atlas con cuentas de usuario en tu aplicación. Esto puede ser útil si necesitas acceder a los datos de un usuario con frecuencia, pero no es necesario usar el proveedor de funciones personalizadas.
A user's custom data document may contain any data. For apps that use the custom function provider, we recommend storing both the user's internal user account ID and their external ID.
Por ejemplo, podrías usar el siguiente formato:
{ "_id": "<Generated ObjectId>", "user_id": "<Internal User ID>", "external_id": "<External User ID>" }
You can use the following approach to create custom user documents for custom function provider users:
Configure datos de usuario personalizados para una colección en su clúster vinculado. El campo ID de usuario almacena el ID de cuenta interno del usuario.
/auth/custom_user_data.json{ "mongo_service_name": "mongodb-atlas", "database_name": "myApp", "collection_name": "users", "user_id_field": "user_id", "enabled": true } Configure el proveedor de autenticación de la función personalizada y devuelva un ID de usuario externo único desde la función de autenticación. App Services almacena este ID en el campo
idde la identidadcustom-functiondel usuario.exports = async function handleCustomFunctionAuth(payload) { const auth = require("some-external-auth-system"); const user = await auth.login(payload); return user.id; }; Configure un disparador de autenticación que detecte eventos
CREATEdel proveedorcustom-function. En la función de disparo, añada un nuevo documento a la colección de datos de usuario personalizada que incluya tanto el ID interno como el externo del usuario.exports = async function onNewCustomFunctionUser({ user }) { // This is the user's internal account ID that was generated by your app const internalId = user.id; // This is the external ID returned from the authentication function const customFunctionIdentity = user.identities.find((id) => { return id.provider_type === "custom-function"; }); const externalId = customFunctionIdentity.id; // Create a custom user data document for the user const mdb = context.services.get("mongodb-atlas"); const users = mdb.db("myApp").collection("users"); return await users.insertOne({ // Include both the internal ID and external ID user_id: internalId, external_id: externalId, // Add any other data you want to include created_at: new Date(), }); };
Iniciar sesión desde un SDK de Realm
Para iniciar sesión desde una aplicación cliente, se debe utilizar una credencial de función personalizada que contenga los datos de la carga útil de inicio de sesión.
Para obtener ejemplos, consulte la documentación de un SDK específico: