Autenticación del sitio en Node.js Registro de usuario

Introducción

Al igual que la autenticación es importante en las API, también es una característica importante en ciertas aplicaciones web, aquellas con páginas y secretos que solo deben ser accesibles para usuarios registrados y autenticados..

En este tutorial, construirá una aplicación web sencilla mientras aprende a crear un registro de usuario..

Configuración de la aplicación

Crea un nuevo directorio desde donde trabajarás. Por el bien de este tutorial, llamé al mío. site-auth. Inicialice npm en el nuevo directorio que acaba de crear. Aquí es cómo inicializar npm.

npm init -y 

los -y la bandera le dice a npm que use las opciones predeterminadas.

Edita las dependencias parte de tu paquete.json archivo para parecerse a lo que tengo en la mía.

# package.json "name": "site-auth", "version": "1.0.0", "description": "," main ":" app.js "," scripts ": " test " : "echo \" Error: no se especificó la prueba \ "&& exit 1", "keywords": [], "author": "izuchukwu1", "license": "ISC", "dependencies": "bcryptjs": "^ 2.4.3", "body-parser": "^ 1.17.1", "connect-flash": "^ 0.1.1", "cookie-parser": "^ 1.4.3", "express": "^ 4.15.2", "express-handlebars": "^ 3.0.0", "express-messages": "^ 1.0.1", "express-session": "^ 1.15.2", "joi": "^ 13.0.1", "mangosta": "^ 4.11.12", "morgan": "^ 1.8.1", "pasaporte": "^ 0.4.0", "pasaporte local": "^ 1.0. 0 "

Con eso hecho, ejecute el comando para instalar las dependencias..

npm instalar

Crea un archivo en tu directorio de trabajo llamado app.js.

Comience por requerir las dependencias que instaló y los archivos necesarios.

# app.js const express = require ('express'); const morgan = require ('morgan') const path = require ('path'); const cookieParser = require ('cookie-parser'); const bodyParser = require ('body-parser'); const expressHandlebars = require ('express-handlebars'); const flash = require ('connect-flash'); const session = require ('express-session'); const mongoose = require ('mongoose') const passport = require ('passport') require ('./ config / passport')

Estas dependencias se instalaron cuando ejecutó npm install. Para usarlos en su aplicación, debe solicitarlos y guardarlos en sus respectivas constantes..

Para este tutorial, utilizará MongoDB como su base de datos. Deberá almacenar la información del usuario en la base de datos. Para trabajar con MongoDB, utilizará la herramienta de modelado Mongoose-a MongoDB para Node.js. Configurar Mongoose es fácil, así.

# app.js mongoose.Promise = global.Promise mongoose.connect ('mongodb: // localhost: 27017 / site-auth')

En este punto, vamos a configurar nuestro middleware.

// 1 const app = express () app.use (morgan ('dev')) // 2 app.set ('views', path.join (__ dirname, 'views')) app.engine ('handlebars', expressHandlebars (defaultLayout: 'layout')) app.set ('view engine', 'handlebars') // 3 app.use (bodyParser.json ()) app.use (bodyParser.urlencoded (extended: false) )) app.use (cookieParser ()) app.use (express.static (path.join (__ dirname, 'public'))) app.use (session (cookie: maxAge: 60000, secreto: 'codeworkrsecret' , saveUninitialized: false, resave: false)); app.use (passport.initialize ()) app.use (passport.session ()) // 4 app.use (flash ()) app.use ((req, res, next) => res.locals.success_mesages = req.flash ('éxito') res.locals.error_messages = req.flash ('error') siguiente ()) // 5 app.use ('/', require ('./ route / index')) app.use ('/ users', require ('./ route / users')) // 6 // captura 404 y reenvía al manejador de errores app.use ((req, res, next) => res.render ( 'extraviado') ); // 7 app.listen (5000, () => console.log ('¡El servidor comenzó a escuchar en el puerto 5000!'))
  1. Express se inicializa y se asigna a aplicación.
  2. Se configura middleware para manejar vistas. Para las vistas, harás uso de bigote daliniano.
  3. Configura middleware para bodyparser, Galleta, sesión, y pasaporte. El pasaporte se utilizará cuando los usuarios quieran iniciar sesión.
  4. En algunos puntos, estarás mostrando mensajes flash. Por lo tanto, necesita configurar middleware para eso, y también crear el tipo de mensajes flash que desea.
  5. Rutas de middleware: esto manejará cualquier solicitud hecha a una ruta URL. Las rutas URL especificadas aquí son para el índice y la ruta de los usuarios..
  6. Middleware para manejar errores 404. Este middleware se activa cuando una solicitud no se asigna a ninguno de los middleware creados anteriormente..
  7. El servidor está configurado para escuchar en el puerto 5000.

Configuración de vistas

Crear un nuevo directorio llamado puntos de vista. Dentro del directorio de vistas, cree otros dos directorios llamados diseños y parciales. Desea lograr una estructura de árbol como esta en sus vistas, así que cree los archivos necesarios en sus respectivos directorios..

├── dashboard.handlebars ├── index.handlebars ├── layouts │ └── layout.handlebars ├── login.handlebars ├── notFound.handlebars ├── parials │ └── navbar.handlebars └── registrar .bigote daliniano

Con eso hecho, es hora de soltar el código..

# dashboard.handlebars  

Dashboard del usuario

Este es un panel de control que debe ser visible solo para los usuarios registrados. Para este tutorial, será tu página secreta..

Ahora la página de índice para la aplicación debería verse así..

# index.handlebars  

Autenticación de sitio!

Bienvenido a bordo.

La aplicación necesita un diseño que se utilizará, y aquí está el diseño que utilizará.

# layout / layout.handlebars    Autenticación de sitio      # mensajes de éxito 
success_messages
/ if # mensajes de error
error de mensajes
/Si
> barra de navegación cuerpo

Necesitará una página de inicio de sesión para usuarios registrados..

# views / login.handlebars 

Por favor, registrese


los extraviado.bigote daliniano archivo será utilizado como su página de error.

# views / notFound.handlebars  

Error

Tu página de registro se supone que se vea así.

Por favor regístrese


Finalmente para tus vistas, aquí tienes tu barra de navegación..

# parciales / navbar.handlebars 

Autenticación de sitio

Con eso hecho, eres bueno para entrar en algunas partes profundas.

Validación de datos

Necesitarás un modelo de usuario. A partir del código de vistas anterior, puede deducir que las propiedades necesarias para el modelo de usuario son correo electrónico, nombre de usuario y contraseña. Crear un directorio llamado modelos, y un archivo llamado usuario.js.

# models / user.js // 1 const mongoose = require ('mongoose') const Schema = mongoose.Schema const bcrypt = require ('bcryptjs') // 2 const userSchema = new Schema (email: String, username: String , contraseña: Cadena, // 3 timestamps: createdAt: 'createdAt', updatedAt: 'updatedAt') // 4 const User = mongoose.model ('user', userSchema) module.exports = User
  1. Importa dependencias y las guarda en constantes..
  2. Se crea un nuevo esquema. Para cada usuario, desea guardar el correo electrónico, nombre de usuario, y contraseña a la base de datos. El esquema muestra cómo se debe construir el modelo para cada documento. Aquí desea que el correo electrónico, el nombre de usuario y la contraseña sean del tipo String.
  3. Para cada usuario guardado en la base de datos, también desea crear marcas de tiempo. Utilizas Mangosta para obtener el Creado en y updatedAt, y esto luego se guarda en la base de datos.
  4. El modelo está definido y asignado a una constante llamada. Usuario, que luego se exporta como un módulo para que se pueda utilizar en otras partes de la aplicación.

Salting y hash de la contraseña

No desea almacenar las contraseñas de los usuarios como texto sin formato. Esto es lo que desea hacer cuando un usuario ingresa una contraseña de texto simple mientras se registra. La contraseña de texto sin formato debe estar grabada con un salt que será generado por su aplicación (usando bcryptjs). Esta contraseña hash se almacena en la base de datos. 

Suena genial, ¿verdad? Vamos a implementar eso en el usuario.js expediente.

# models / user.js module.exports.hashPassword = async (password) => try const salt = await bcrypt.genSalt (10) return espere a bcrypt.hash (password, salt) catch (error) arrojar un nuevo error ('Falló el hashing', error)

Acaba de crear un método que se llamará en los eventos de registro de usuarios. El método recibirá la contraseña de texto sin formato que ingresó el usuario. Como mencioné anteriormente, la contraseña de texto sin formato se procesará usando un salt generado. La contraseña con hash será devuelta como la contraseña para el usuario..

Índice y Rutas de Usuarios 

Crear un nuevo directorio llamado rutas. En este nuevo directorio, crea dos nuevos archivos: index.js y usuarios.js.

los index.js El archivo será muy simple. Se asignará al índice de su aplicación. Recuerda que configuraste middleware para tus rutas en tu app.js archivo cuando hiciste esto.

app.use ('/', require ('./ route / index')) app.use ('/ users', require ('./ route / users'))

Por lo tanto, su ruta de índice, que simplemente muestra la página de índice, debería tener este aspecto.

# route / index.js const express = require ('express') const router = express.Router () router.get ('/', (req, res) => res.render ('index')) módulo .exports = enrutador

Ahora a la ruta de los usuarios. Por ahora, este archivo de ruta hará cuatro cosas..

  1. Requieren dependencias. Necesitará las dependencias que instaló usando NPM.
  2. Validar entradas de usuario. Desea asegurarse de que el usuario no envíe un formulario vacío. Todas las entradas son necesarias y todas deben ser del tipo Cadena. El correo electrónico tiene una validación especial llamada .correo electrónico() lo que garantiza que lo que se ingresa coincida con el formato del correo electrónico, mientras que la contraseña se valida mediante una expresión regular. Para la contraseña de confirmación, desea que sea la misma que la contraseña ingresada. Estas validaciones se realizan utilizando Joi.
  3. Configure su enrutador. los OBTENER solicitud hace que la página de registro, mientras que la ENVIAR la solicitud se activa cuando el usuario pulsa el botón para enviar el formulario.
  4. El router se exporta como un módulo..

Así es como se ve el código.

# route / users.js const express = require ('express'); const router = express.Router () const Joi = require ('joi') const passport = require ('passport') const User = require ('… / models / user') // esquema de validación const userSchema = Joi.object ( ) .keys (email: Joi.string (). email (). required (), nombre de usuario: Joi.string (). required (), contraseña: Joi.string (). regex (/ ^ [a-zA- Z0-9] 6,30 $ /). Obligatorio (), confirmación Contraseña: Joi.any (). Válido (Joi.ref ('contraseña')). Requerido ()) router.route ('/ register' ) .get ((req, res) => res.render ('register')) .post (async (req, res, next) => try const result = Joi.validate (req.body, userSchema ) si (result.error) req.flash ('error', 'Los datos ingresados ​​no son válidos. Inténtelo de nuevo.') res.redirect ('/ users / register') return const user = await User.findOne ( 'email': result.value.email) if (usuario) req.flash ('error', 'El correo electrónico ya está en uso.') res.redirect ('/ users / register') return const hash = aguarda User.hashPassword (result.value.password) elimina result.value.confirmationPassword result.value.password = hash const newUser = await new User (result.value) espera a newUser.save () req.flash ('success', 'Registro con éxito, sigue adelante e inicia sesión.') res.redirect ('/ users / login') catch (error ) siguiente (error)) module.exports = router 

Echemos un vistazo más profundo a lo que está sucediendo en ese ENVIAR solicitud.

Los valores introducidos en el formulario de registro son accesibles a través de req.body, y los valores se ven asi.

valor: correo electrónico: '[email protected]', nombre de usuario: 'izu', contraseña: 'chinedu', confirmación de contraseña: 'chinedu',

Esto se valida utilizando el usuarioSchema usted creó anteriormente, y los valores ingresados ​​por el usuario se asignan a una constante llamada resultado.

Si se produce un error debido a la validación, se muestra un mensaje de error al usuario y se realiza una redirección a la página de registro..

De lo contrario, intentamos encontrar si existe un usuario con la misma dirección de correo electrónico, ya que no desea tener dos o más usuarios con la misma dirección de correo electrónico. Si se encuentra un usuario, se le dice al usuario que la dirección de correo electrónico ya está en uso.

En un escenario en el que ningún usuario registrado tiene esa dirección de correo electrónico, el siguiente paso es codificar la contraseña. Aquí es donde llamas al hashPassword Método que creó en su archivo user.js. La nueva contraseña hash se asigna a una constante llamada hash.

No hay necesidad de almacenar el confirmación de contraseña en la base de datos Por lo tanto, esto se elimina. La contraseña disponible desde el resultado sigue siendo la contraseña simple. Como no desea almacenar la contraseña simple en su base de datos, es importante reasignar el valor de la contraseña al hash que se creó. Esto se hace con una línea de código..

result.value.password = hash

La nueva instancia de usuario se guarda en la base de datos. Se muestra un mensaje flash que indica que el registro fue exitoso, y el usuario es redirigido a la página de inicio de sesión.

Inicie su servidor desde su terminal ejecutando:

nodo app.js

Dirija su navegador a http: // localhost: 5000 y debería ver su nueva aplicación.

Conclusión

Ahora ya sabe cómo implementar la función de registro en una aplicación web Node. Ha aprendido la importancia de validar las opiniones de los usuarios y cómo hacerlo utilizando Joi. También hiciste uso de bcryptjs Sal y hash tu contraseña.

A continuación, verá cómo implementar una función de inicio de sesión para usuarios registrados. Confío en que hayas disfrutado!