https://d226lax1qjow5r.cloudfront.net/blog/blogposts/using-vonage-apis-with-mongodb-atlas-part-4/mongodb_vonage_p4.png

Uso de las API de Vonage con MongoDB Atlas - Parte 4

Publicado el May 16, 2023

Tiempo de lectura: 14 minutos

En esta serie:

Seguimos sumergiéndonos en MongoDB Atlas y su uso con varias API de Vonage. En la Parte 1, echamos un vistazo a lo que es MongoDB Atlas y algunos de los servicios que ofrece. En la Parte 2, utilizamos Vonage Verify para aumentar la seguridad del usuario durante la autenticación. La Parte 3 giró en torno al contacto con el cliente para su pedido y lo que podemos hacer cuando los clientes necesitan hablar con el restaurante. En la Parte 4, pondremos en marcha el sistema de autenticación de usuarios de Atlas.

Descarga de la autenticación de usuarios

Un área común que comparten las aplicaciones web es la necesidad de autenticar a los usuarios. Los frameworks ayudan a manejar algo de esto, pero cada aplicación construye código similar para hacer una cosa - confirmar las credenciales de un usuario. Podemos usar MongoDB Atlas tiene un sistema incorporado para autenticar y gestionar usuarios.

Este sistema es diferente de la autenticación que hacemos a MongoDB y es un servicio que proporciona Atlas. Puedes gestionar usuarios a través de Atlas como un servicio de autenticación de terceros (para tu aplicación). Usar Atlas te permite soportar muchos tipos de autenticación diferentes de forma segura.

Para mostrar esto, el backend administrativo de nuestra demo utiliza autenticación Atlas en lugar de Verify. Este backend nos permitirá gestionar el inventario que mostramos a los usuarios y los pedidos que han entrado. También nos permitirá unirnos a cualquier reunión de Video que los clientes hayan iniciado. Además, nos permitirá ver qué ocurre si queremos integrar el acceso a MongoDB en nuestra aplicación en lugar de depender de una API de backend.

Configuración de la autenticación

Atlas admite tanto una interfaz web como archivos de configuración para muchas funciones centradas en las aplicaciones. En el tutorial utilizaremos la interfaz web para la configuración, pero también puedes utilizar los archivos de ejemplo suministrados en el repositorio de demostración. Estos archivos funcionan con la herramienta Realm CLIy te los hemos proporcionado para que los compares con la interfaz web. Si está empezando, le recomiendo que utilice la interfaz de usuario web, pero en una aplicación gestionada, querrá almacenar la configuración y utilizar la CLI de Realm para desplegar los cambios de configuración. La demo incluye una carpeta app-service/ con archivos de ejemplo que puedes editar para empezar.

Las Apps de Atlas son una combinación de detalles de configuración y código desplegado. La interfaz de Apps facilita el trabajo con la configuración y el código que un desarrollador ha descargado en los servicios de Atlas.

Por ahora, vamos a utilizar la interfaz web. Una vez que inicie sesión en su proyecto, haga clic en "App Services" en la barra de navegación secundaria superior. Aparecerá una lista de proyectos de aplicaciones configurados. Si ésta es la primera aplicación con la que trabajas, aparecerá una ventana que te llevará a App Services. Selecciona "Construye tu propia aplicación" por ahora, ya que nosotros nos encargaremos de todo para el tutorial.

New Atlas App dialogNew Atlas App dialog

La siguiente pantalla tendrá algunas preguntas de configuración. Nuestra Fuente de Datos, que es el cluster que usamos, debería estar rellenada. Selecciona el que utilizas para el tutorial si tienes varios clusters. También puedes cambiar el nombre de la aplicación. Yo llamaré a la aplicación "Frontend" ya que este servicio de aplicación manejará nuestro frontend JavaScript para las páginas de administración. Haga clic en Crear servicio de aplicación para continuar, y luego Cerrar guías para cerrar la ventana de inicio.

Esto nos lleva al panel de control de Applications para nuestra aplicación Frontend. Como puedes ver, puedes hacer muchas cosas con una aplicación Atlas, pero por ahora, nos centraremos en el uso de la autenticación de usuario. En la sección "Acceso a datos" de la barra lateral, haga clic en Autenticación para que podamos empezar a configurarla.

User authentication optionsUser authentication options

Como ya hemos mencionado, Atlas admite varios tipos de autenticación. Por ahora, sólo nos preocuparemos de "Correo electrónico/Contraseña". Haz clic en el botón Editar para empezar a configurarlo.

En la página de configuración, activa la opción "Provider Enabled". Para el tutorial, vamos a confirmar automáticamente a los nuevos usuarios, así que adelante y selecciona también "Confirmar usuarios automáticamente" En una aplicación de producción, querrás que el usuario verifique su correo electrónico para validar que la dirección de correo electrónico existe, pero podemos omitir ese paso por ahora. Aunque no lo implementaremos, debe introducir una "URL de restablecimiento de contraseña". Por ahora, introduzca "https://example.com/reset" para satisfacer el formulario. Haga clic en Guardar borrador cuando haya terminado.

Email/Password optionsEmail/Password options

Espera, "¡¿Guardar borrador?!" Si pasas del panel que aparece, todos los cambios que hagas en Atlas se considerarán cambios de borrador. Puedes preparar un conjunto de borradores diferentes y desplegarlos cuando todo esté configurado. Toda esta información se guarda en archivos de configuración que pueden cargarse y descargarse mediante la CLI de Realm, y los archivos mencionados anteriormente se guardan en app-service/ a modo de ejemplo.

Una vez que haya realizado un cambio, verá un banner en la parte superior de la página que ahora dice "Se han realizado cambios" con un botón para revisarlos. Haga clic en Revisar borrador y desplegar. Verás un blob JSON que es una diferencia de texto entre la configuración antigua y la nueva. Esto le resultará muy familiar si ha utilizado el sistema de solicitudes de GitHub. Como acabamos de hacer este cambio, haz clic en Despliegue. Estos ajustes se enviarán al servicio de aplicaciones y podremos empezar a utilizar la autenticación.

Deployment Diff dialogDeployment Diff dialog

Ahora necesitamos un usuario. Haga clic en Usuarios de la aplicación en la barra lateral, y luego en Añadir nuevo usuario Añadir nuevo usuario. Introduzca una dirección de correo electrónico y una contraseña válidas y, a continuación, haga clic en Crear. Crear usuarios de esta manera no será escalable, por lo que existen opciones para crear usuarios programáticamente a través de un proceso de registro, pero por ahora, usaremos uno que hagamos a mano.

En este punto, la autenticación está configurada para nuestra aplicación. Podríamos utilizar el SDK de MongoDB Realm para autenticar un usuario, pero nuestro usuario actual no es más que una dirección de correo electrónico y una contraseña. No podemos almacenar información extra o denotar que el usuario es un usuario administrativo. Aquí es donde entran los Datos Personalizados de Usuario. Podemos vincular un usuario a una colección de documentos que albergará contenido adicional del usuario, como nombre, teléfono, o incluso si está marcado como administrador.

Haga clic en Configuración de usuario. Esto hará que aparezca la página de configuración para la vinculación de nuestros datos de usuario.

Custom User Information settingsCustom User Information Settings

A continuación, seleccione el clúster y la base de datos en los menús desplegables "Nombre del clúster" y "Nombre de la base de datos", respectivamente. Para el "Nombre de la colección", seleccione "Crear nueva colección", lo que hará que aparezca un cuadro de texto adicional. En este nuevo cuadro, introduzca user_custom_data y haga clic en Crear. Esto almacenará nuestros datos personalizados en una colección separada de nuestros datos de cliente.

En el campo "ID de usuario", introduzca user_id. Esto actuará como una clave externa para el usuario al que se adjuntan los datos. Aunque mencionamos no hacerlo en la Parte 3, esta es una de esas ocasiones en las que hacer algo como una clave foránea de base de datos relacional tiene sentido. La tabla que almacena los datos de usuario está totalmente gestionada, por lo que no tenemos acceso directo a ella, lo que significa que no podemos incrustar estos datos en el registro de usuario ni queremos almacenar las credenciales de usuario con los datos de usuario.

Una vez hecho esto, haga clic en Guardar borrador y luego Revisar borrador y desplegar para guardar la nueva configuración.

Una vez desplegado, vuelva a la sección Usuarios . Queremos marcar nuestro nuevo usuario como administrador, así que vamos a crear los datos de usuario personalizados. Necesitaremos el ID del usuario que acabamos de crear, así que copia ese ID para el usuario. A continuación, vuelva a Servicios de datos en la barra de navegación superior y vaya a Examinar colecciones.

Tenemos que hacer una nueva colección, así que pasa el ratón sobre el restaurant_pos_demo nombre de la base de datos, y aparecerá un + a la derecha del texto. Haga clic en él e introduzca user_custom_data como nombre de la colección. Haz clic en Crear para crear una colección vacía. Una vez que se crea, haga clic en Insertar documentocambia a la vista {} y pega el siguiente documento JSON.

{
 "user_id": "<user-id-we-just-copied>",
 "admin":true
}

Cuando lleguemos al código donde iniciamos sesión dentro de nuestra aplicación, la bandera admin se añadirá al usuario cuando sea devuelto. También puedes añadir arbitrariamente cualquier información a este documento para cualquier otra información del usuario que quieras rastrear en tu aplicación. Para nuestro tutorial, necesitamos un booleano admin bandera.

Seguridad de las consultas

Veremos una sección más mientras estemos en la interfaz web de Atlas. Una característica que utiliza nuestro backend administrativo para el tutorial es la consulta de la base de datos directamente desde nuestra aplicación del lado del cliente. En muchas aplicaciones, como el lado cliente de nuestro tutorial, tenemos una API backend que accede a nuestros datos. Atlas nos permite consultar la base de datos desde el navegador mediante una combinación de autenticación de usuario, que acabamos de configurar, y controles de acceso a datos basados en reglas.

Haga clic en Reglas de la pantalla App Services en "Acceso a datos". Esto le llevará a la pantalla Reglas, donde podemos controlar el acceso de los usuarios autenticados. En este momento, nuestra aplicación no realiza ninguna comprobación de autorización, pero añadirla es cuestión de unos pocos clics.

Atlas App Rules configurationAtlas App Rules configration

Queremos asegurarnos de que cualquier usuario que acceda sea un administrador, ya que los administradores serán los únicos que actualmente deberían acceder a estos datos. Para nuestra aplicación, sólo queremos permitir a alguien con la bandera admin en su Account (¿ves por qué lo hemos configurado antes?). Puedes imponer restricciones en toda la base de datos o por esquema. Dado que sólo permitimos a nuestro administrador acceder directamente a la base de datos, podemos añadir estas reglas a la propia base de datos. En la pantalla Reglas, haga clic en Funciones y filtros predeterminados justo encima del nombre de la base de datos.

Podemos establecer algunas funciones preestablecidas, como denegar todo o permitir todo. Queremos crear una regla que utilice nuestros datos personalizados, así que baja y haz clic en Saltar (empezar de cero).

New Atlas App dialogAdmin-Write rule config

Tenemos que darle un nombre a nuestro rol, así que vamos a llamarlo "admin-write". A continuación, tenemos que establecer las reglas para cuando se aplicará nuestro rol. Como nos preocupa tener acceso a los datos cuando somos administradores, podemos establecer una regla sencilla que garantice que el usuario tiene un atributo de datos personalizado llamado admin y que esté configurado como true. Copia y pega el bloque de JSON de abajo en el editor.

{
    "%%user.custom_data.admin": true
}

%%user indica al sistema de reglas que compruebe el usuario autenticado. Cuando nos autenticamos, la información almacenada en user_custom_data se adjunta al usuario devuelto y se asigna a la propiedad custom_data propiedad. Usted puede agregar cualquier número de reglas para ayudar a hacer esto tan granular como desee en una aplicación real.

Debajo de esto, podemos establecer los permisos de los documentos. Como somos un usuario administrador, seleccionamos "Insertar", "Eliminar" y "Buscar", lo que dará a cualquier usuario administrador acceso completo a todos los documentos de cualquier colección. Por último, tenemos los permisos de campo. Puedes establecer reglas de acceso hasta el archivo específico de una colección. Ahora mismo, selecciona "Leer y escribir en todos los campos".

Estas dos configuraciones serán más útiles cuando quieras hacer cosas como todas las vistas de sólo lectura a roles de usuario específicos o restringir campos de roles que sólo tienen algún acceso a la información. Estas reglas se pueden utilizar junto con reglas de filtro más amplias que restringen los datos que se pueden obtener de una consulta.

Guarde todos estos ajustes y, a continuación, revise y despliegue nuestros nuevos controles de acceso.

Lo último que tenemos que hacer es indicar a nuestra aplicación con qué aplicación de Atlas debe comunicarse. En la página de inicio de la aplicación Atlas que estamos utilizando, cerca de la parte superior hay un ID de aplicación. Cópialo e introdúcelo en el archivo .env de la aplicación web en VITE_REALM_ID.

App ID locationApp ID location

¿Ya podemos entrar?

¡Sí!

Vaya a http://localhost:5173/login e inicia sesión con la dirección de correo electrónico y la contraseña que asignaste al usuario en Atlas. Deberías ser recibido con una pantalla de inventario y la opción de añadir nuevos platos. Si ves esto, ¡estás autenticado!

Tutorial Admin AreaTutorial Admin Area

MongoDB Atlas tiene un navegador SDK que se puede utilizar para ponerse en contacto con nuestro clúster y aplicación Atlas. Debemos tomar una dirección de correo electrónico y una contraseña para nuestra aplicación y pasarla a las llamadas de autenticación del SDK.

import { MongoDBRealmError } from 'realm-web';
import { ref } from 'vue'
import { useRouter } from 'vue-router';
import { authenticationStore } from '../stores/authenticationStore';

const router = useRouter();
const username = ref('')
const password = ref('')
const authStore = authenticationStore()

const login = async () => {
    try {
        await authStore.login(username.value, password.value)
        router.push({ name: 'inventory.home' });
    } catch (error) {
        if (error instanceof MongoDBRealmError) {
            console.log(error.errorCode)
        }
    }
}

El código VueJS es relativamente mínimo. Nuestro componente componente Login.vuetenemos una tienda de autenticación, que al igual que nuestro carrito de la compra es una envoltura para hacer más fácil pasar la información del usuario conectado. Esta tienda utilizará el SDK para iniciar sesión. En esta página, sólo tenemos que esperar a que el usuario se registre usando el formulario y llamar a authStore.login() con el nombre de usuario y la contraseña.

import { defineStore } from 'pinia'
import * as Realm from 'realm-web'

const realmApp = new Realm.App({id: import.meta.env.VITE_REALM_ID})

export const authenticationStore = defineStore('authenticationStore', {
    state: () => {
        return {
            token: null,
            user: null,
        }
    },
    actions: {
        async login(username, password) {
            const creds = Realm.Credentials.emailPassword(username, password);
            this.user = await realmApp.logIn(creds)
            return this.user
        },
        setToken(token: string) {
            this.token = token
        },
        logout() {
            this.token = null
        }
    }
})

En almacén de autenticación es poco más que una envoltura para el SDK de MongoDB y algunos lugares para guardar la información del usuario. Creamos un almacén usando Pinia y creamos un nuevo objeto Realm.App() con un enlace a nuestro App ID que añadimos a nuestro archivo .env archivo. Dentro de nuestro authenticationStore hay un método login() método llamado Realm.Credentials.emailPassword(). Esto genera un conjunto de credenciales de usuario que podemos pasar al objeto app para autenticar. Si la llamada a realmApp.login() tiene éxito, obtenemos un usuario. Almacenamos ese usuario y podemos sacarlo del almacén en cualquier momento.

A partir de este momento, nuestro usuario se considera autenticado. En cualquier momento podemos comprobar authenticationStore.user y si existe, estamos autenticados. Como hemos iniciado sesión en Atlas a través del SDK, ahora también podemos acceder a la base de datos directamente desde el front end. Hacemos esto a través de un Almacén de base de datos. Todo lo que hace este almacén es mantener una conexión con nuestro clúster MongoDB, y utiliza las credenciales del usuario conectado.

Esto es muy potente, ya que podemos realizar búsquedas de datos directamente en el navegador en lugar de depender de nuestra API backend. Podemos bloquear este acceso sólo a los usuarios administradores utilizando las reglas que establecimos en la configuración de la aplicación Atlas. Si quisiéramos deshacernos de todo el código MongoDB de nuestra API backend, podríamos añadir reglas y filtros adicionales para bloquear a los usuarios y que sólo vean los datos a los que pueden acceder. Es una gran manera de esbozar una aplicación rápidamente.

import { defineStore } from 'pinia'
import { authenticationStore } from './authenticationStore'

const authStore = authenticationStore()
const dataSource = import.meta.env.VITE_MONGODB_DATA_SOURCE
const databaseName = import.meta.env.VITE_MONGODB_DATABASE

export const mongodbStore = defineStore('mongodbStore', {
    state: () => {
        return {
            restaurantDb: authStore.user.mongoClient(dataSource).db(databaseName),
        }
    },
    actions: {
        getInventoryCollection() {
            return this.restaurantDb.collection('inventory')
        }
    }
})

El almacén de base de datos es muy mínimo. Facilitamos la extracción del objeto de base de datos y la colección desde la conexión Realm que establecimos en el almacén de autenticación. Luego podemos consultar la base de datos desde nuestro código VueJS, como en el componente componente Inventario:

import { ref } from 'vue';
import { mongodbStore } from '../stores/mongodbStore';

const dbStore = mongodbStore()
let inventory = ref(Array());

async function getInventory() {
    const dishes = await dbStore.getInventoryCollection().find()
    inventory.value = Array()
    dishes.forEach(dish => {
        if (dish.name) {
            inventory.value.push(dish)
        }
    })
}

En nuestro componente VueJS, introducimos la base de datos como mongodbStore. A continuación, podemos utilizar la sintaxis del SDK de MongoDB para encontrar documentos que podamos utilizar. Como queremos todos los documentos de la colección de inventario, podemos usar dbStore.getInventoryCollection().find() para devolver todos los documentos a los que tenemos acceso. A continuación, podemos insertarlos en un objeto VueJS ref() para mostrarlos en la página.

Una parte esencial de esa secuencia es "tenemos acceso a". La página Reglas de la aplicación Atlas puede utilizarse para restringir qué documentos podemos ver. Por ejemplo, es habitual vincular un documento a un usuario, como un Autor (o, en nuestro caso, la persona que hizo un pedido). Se puede configurar un Filtro que sólo devuelva los pedidos de ese usuario, incluso si se hizo una llamada a find() para devolver todo. Las restricciones y filtros configurados en la sección Reglas de la aplicación Atlas aumentarán cualquier consulta realizada por el navegador.

Conclusión

Atlas Applications puede ayudar a reducir drásticamente parte del tiempo de desarrollo de aplicaciones a través de cosas como la autenticación de usuarios y el acceso a consultas. Podemos omitir por completo muchas funcionalidades, como la capacidad de publicar funciones en una plataforma sin servidor o habilitar una pasarela de API para crear una arquitectura de microservicios para su navegador o aplicación móvil. Existen incluso sistemas de replicación de datos para proporcionar capacidades offline y de sincronización de datos a las aplicaciones.

Ahora que ya hemos iniciado sesión, nos queda una pieza más en la que fijarnos. Cuando un usuario tiene un problema, ¿cómo lo sabemos? Veremos la pantalla de pedidos del administrador y cómo podemos aprovechar la mensajería In-App de Vonage para obtener notificaciones en el navegador de que un usuario ha enviado una solicitud de reunión y cómo usamos la Meetings API para darle al restaurante capacidades de alojamiento de video que no están disponibles para el cliente.

Compartir:

https://a.storyblok.com/f/270183/384x384/3bc39cbd62/christankersley.png
Chris TankersleyGestor de herramientas de relaciones con los desarrolladores

Chris es el director de herramientas de relaciones con los desarrolladores y dirige el equipo que crea sus herramientas favoritas. Lleva más de 15 años programando en varios lenguajes y tipos de proyectos, desde trabajos para clientes hasta sistemas de big data a gran escala. Vive en Ohio, donde pasa el tiempo con su familia y jugando a Video y TTRPG.