Explorando Couchbase y N1QL a través de Touchbase usando Node.js y Angular.js - Parte 3: Autenticación de usuario basada en sesión

Parte 3: Modelos de inicio de sesión

Hasta ahora, Parte 0 y Parte 1 cubren el modelo de datos y el documento de usuario utilizados en la aplicación, seguidos de Parte 2 donde verificamos las cuentas a través del correo electrónico utilizando Nodemailer y Sendgrid. Estas son una parte fundamental para conseguir que un usuario se inicie en cualquier sitio web de medios sociales, pero ahora debemos asegurarnos de que pueden iniciar sesión y acceder al contenido en nuestra red social. ¡Vamos a empezar!

Materiales necesarios:

  • Node.js
  • Express

Módulos de nodo utilizados:

  • SDK de Couchbase Node.js con N1QL
  • body-parser
  • uuid

Primero tenemos que autenticar a nuestros usuarios. El punto final de la API para ello es /api/loginAuth.

API "/api/loginAuth

La autenticación comienza asegurándose de que tanto el correo electrónico como la contraseña se pasan correctamente al back-end. Si faltan, se devolverá un error. En la implementación actual de esta API, el error se muestra en el front-end con un error Angular.js, ng-messages. Tenga en cuenta que también enviamos el nombre de usuario y la contraseña a este punto final a través de una solicitud POST. Esto garantiza un poco más de seguridad que un GET, ya que la URL no expondrá información secreta. Por supuesto, un despliegue adecuado de la aplicación debería incluir HTTPS para evitar ataques man-in-the-middle.

Tras la primera validación, el User.advancedSearch se ejecuta para encontrar el documento de la dirección de correo electrónico que el usuario está buscando. Lo ideal es que la función devuelva como resultado la dirección de correo electrónico exacta que tiene el usuario. Como se puede ver, el primer fragmento de código de la API loginAuth, 'if (x.length === 0)'En primer lugar, comprueba si la dirección de correo electrónico está registrada y, en caso contrario, emite un mensaje de error. En segundo lugar, comprueba que la combinación de nombre de usuario y contraseña es válida, llamando a la función User.validatePassword que se asegura de que la versión hash de la contraseña introducida por el usuario coincide con la versión hash almacenada en el documento del usuario. Esto utiliza la misma función hash que utilizamos en el documento de usuario original que creamos en la sección 'Usuario.crear' función.

Función User.validatePassword

A continuación, comprueba que el correo electrónico del usuario está verificado. Si no está seguro de cómo funciona esto, consulte parte 2 de esta serie. En resumen, hay un atributo 'login.emailVerified' que cambiaría si el usuario verifica su correo electrónico. Este es un atributo booleano, por lo que comprobamos para asegurarnos de que se evalúa como 'true', y si no lanzamos un mensaje de error para decirle al usuario que su correo electrónico aún no está verificado.

Por último, si se cumplen todas las condiciones anteriores, pasamos al proceso de inicio de sesión del usuario. Esto incluye añadir la hora actual al array, 'timeTracker.loginTimes', en el documento de usuario correcto. Para ello se utiliza el método Usuario.addLoginTime que se encuentra en models/usermodel.js.

Función User.addLoginTime

Esta función usa una consulta N1QL para tomar el array del usuario y esencialmente igualarlo al mismo array, pero con la hora actual añadida al array 'timeTracker.loginTimes'. Actualmente no hay forma de añadir algo a un array existente usando N1QL, así que esta es una solución alternativa hasta que se añada esa funcionalidad. El ACTUALIZACIÓN garantiza que la clave que buscamos ya existe y que sólo estamos actualizando una matriz existente.

NOTA: Asegúrese siempre de utilizar el UTILIZAR TECLAS siempre que desee buscar un ID de documento específico. Utilización de WHERE META(nombrecubo).id=var' o cualquier otro DONDE no utiliza la super rápida interfaz K-V a Couchbase y puede ser inconsistente con tus cambios. En este ejemplo usamos UTILIZAR TECLAS para la velocidad y pasar todas nuestras nuevas variables en un array al SDK de Node.js para que lo utilice en la consulta. Esto asegura que la consulta será más segura y evitará la inyección N1QL, similar a la inyección SQL. Los lugares donde se colocarán estos elementos del array en la consulta se indican con un '$'. El entero especificado junto al sybmol '$' especifica qué elemento del array se utilizará. La indexación comienza en 1.

Una vez ejecutado con éxito, podemos volver a rutas/routes.js a nuestro punto final de la API y mire el Sesión.crear que se ejecutará a continuación. Aquí, llegamos al principio de la creación de una aplicación más segura. Usando Sesión.crearpasamos el ID del usuario, como hicimos en la última función. Esto se puede encontrar en modelos/sessionmodel.js.

Función session.create

Esta función toma el ID de usuario y genera un documento de sesión que tiene su propio identificador único, sessionID, y también el ID de usuario del usuario asociado, para poder identificarlo. El campo 'userID' es útil para cuando queramos crear una página de 'Mi Perfil', o identificar quién puede haber hecho un determinado post en nuestra red social. Usamos una simple inserción del SDK de Couchbase para añadir este documento. Luego añadimos una expiración al documento para que expire una hora después de ser añadido (3600 milisegundos). Después de que un usuario esté conectado durante más de una hora, tendrá que conectarse de nuevo. Una posible mejora aquí podría ser utilizar la función tocar() para extender la sesión mientras está en uso. Una vez creado este documento, enviamos un callback con el sessionModel, y luego en nuestro rutas/routes.js enviamos un objeto con el identificador de sesión y la fecha de caducidad al front-end. Aquí este sessionID se almacenará en el localStorage del navegador, para poder acceder a él siempre que sea necesario.

Después de añadir el sessionID al localStorage, lo enviamos en la cabecera de las peticiones HTTP para cualquier ruta protegida. Una ruta protegida sería cualquier punto final de la API que tenga información segura a la que sólo deberían acceder los usuarios que hayan iniciado sesión. Para este proyecto utilicé Angular.js, así que puse el sessionID de localStorage en el encabezado $http para cada solicitud de API, que se puede ver en el archivo $scope.getAllUsers función.

Función front-end $scope.getAllUsers

En /api/advancedSearch es un ejemplo de ruta protegida, y se ve afectada por lo anterior $scope.getAllUsers función. En el código de la función /api/advancedSearch y observará que llama a Sesión.authy luego un callback en los argumentos de la función.

API "/api/advancedSearch

En Sesión.auth función en modelos/sessionmodel.js toma el sessionID de la cabecera de la petición, haciendo una operación de división en la cabecera $http para analizarla. El identificador de sesión puede estar en el cuerpo de la petición, como en el caso de la subida de imágenes, que se gestiona en el comando Sesión.auth también. Una vez que el sessionID se toma de la cabecera, o de alguna otra parte de la petición, entonces se realiza una consulta N1QL para encontrar el documento de sesión. De nuevo, UTILIZAR LLAVES se utiliza para mantener la velocidad en mente. En el caso de que no se encuentre ningún documento con el sessionID que pasamos, lo que probablemente significa que ha expirado después de una hora, entonces se envía una respuesta con un objeto. Esto puede ser manejado de muchas maneras diferentes en el front-end, y en mi implementación, simplemente envío al usuario de vuelta a la página de login si ('!currentSession').

Función session.auth

Esta seguridad basada en la sesión mantiene el sitio web seguro, ya que todo el control de acceso se verifica en el back-end. A diferencia de una simple cookie, donde el usuario se desconecta si la cookie expira, esto da al desarrollador un control total sobre el inicio de sesión. El mero uso de cookies que caducan permite que el javascript del front-end sea fácilmente borrado o alterado para obtener acceso a la información del sitio. La razón por la que las /api/loginAuth también pasa la caducidad del documento de sesión al front-end es para permitir a otros desarrolladores añadir potencialmente cookies que caducan en el front-end si lo desean.

Si el Sesión.auth tiene éxito y encuentra el documento correcto, pasa el ID de usuario del documento al objeto de solicitud, y cualquier otra función del punto final de la API puede acceder a él para recibir información específica del usuario para cosas como "Mi perfil", o almacenar el ID del usuario en documentos para sus publicaciones.

Con esto concluye nuestro cuarto tutorial sobre Touchbase, y espero que haya sido útil para entender un método de mantener una aplicación segura. Hay otras alternativas como los tokens web JSON, o OAuth 2.0, pero en este caso elegí un enfoque basado en sesiones y espero que te ayude a entender este método de autenticación de usuarios. Si tienes alguna pregunta, comentario u opinión, por favor comenta abajo.

Comparte este artículo
Recibe actualizaciones del blog de Couchbase en tu bandeja de entrada
Este campo es obligatorio.

Autor

Publicado por Pranav Mayuram

Pranav Mayuram es pasante de lenguaje de consulta N1QL, Couchbase. Construyó una plataforma de red social, Touchbase, usando Couchbase Server, Node.js, Express & Angular.js.

Deja un comentario

¿Listo para empezar con Couchbase Capella?

Empezar a construir

Consulte nuestro portal para desarrolladores para explorar NoSQL, buscar recursos y empezar con tutoriales.

Utilizar Capella gratis

Ponte manos a la obra con Couchbase en unos pocos clics. Capella DBaaS es la forma más fácil y rápida de empezar.

Póngase en contacto

¿Quieres saber más sobre las ofertas de Couchbase? Permítanos ayudarle.