Registro y Login de Usuarios

03/11/2016 Register and Login

Introducción

En este apartado haremos la implementación del MVC, mediante la construcción de un sistema completo de Registro y Login de Usuarios. Un Usuario podrá acceder a una pantalla de registro donde podrá registrarse ingresando Nombre y Contraseña.

El sistema aquí expuesto responde a un sistema tradicional de Login/Registro de Usuarios. La mayoría de las Aplicaciones Express son usadas como SPA, de manera que, para cosntruir estos sistemas, utilizan mecanismos de JWT implementando OAuth o similar.

No explicaremos ese tipo de mecanismos aquí porque es muy popular y ya hay demasiado tutoriales sobre ello. Por esta razón, en este capítulo se expone la forma tradicional de este sistema mediante peticiones y respuestas Http con recarga de vistas.

Las rutas

El punto de entrada siempre son las rutas. Definiremos todas aquellas necesarias para un sistema de login y registro completo, esto es:

  • login: De tipo GET. Devuelve un formulario de registro.
  • login: De tipo POST. Recibe datos un formulario.
  • register: De tipo GET. Devuelve un formulario de registro.
  • register: De tipo POST. Recibe datos de un formulario.
  • logout: De tipo GET. Destruye la sesión de un Usuario logado.

Definiremos todas esas rutas en un nuevo archivo llamado auth.js el cual ubicaremos dentro del directorio routes. En él escribiremos:

                
                    var express = require('express');
                    var router = express.Router();
                    var passport = require('passport');
                    var authCtrl = require('../controllers/AuthCtrl');

                    router.get('/login', authCtrl.getLogin);

                    router.post('/login', authCtrl.login);

                    router.get('/logout', authCtrl.logout);

                    router.get('/register', authCtrl.getRegister);

                    router.post('/register', authCtrl.register);
                
            

Con todas las url's ya mapeadas, procederemos a crear el Controlador AuthCtrl.

El Controlador

Crearemos el archivo AuthCtrl dentro de controllers. Este Controlador deberá comunicarse con el modelo User que definiremos con Mongoose para realizar consultas a la BBDD y crear registros (al registrarse un Usuario). En este fichero escribiremos:

                
                    'use strict';
                    const mongoose = require('mongoose');

                    const User = mongoose.model('User');
                    const passport = require('passport');

                    module.exports.getRegister = (req, res) => {
                        res.render('auth/register', { });
                    };

                    module.exports.register = (req, res) => {
                        let salt = User.getSalt();
                        User.create({
                            'name': req.body.name,
                            'email': req.body.email,
                            'password': User.hashPassword(req.body.password, salt),
                            'passwordSalt': salt
                        }, function(err, user){
                            if(err) console.log(err);

                            req.login(user, function(err) {
                                if (err) console.log(err);
                                console.log(`User ${req.user.name} registered`);
                                return res.redirect('/'); //res.redirect('/users/' + req.user.username);
                            });
                        });
                    };

                    module.exports.getLogin = (req, res) => {
                        res.render('auth/login', {});
                    };

                    module.exports.login = (req, res, next) => {
                        passport.authenticate('local', function(err, user, info) {
                            if (err) { return next(err); }
                            if (!user) {
                                return res.redirect('/auth/login');
                            }
                            req.logIn(user, function(err) {
                                if (err) { return next(err); }
                                //return res.redirect('/users/' + user.username);
                                console.log(`User ${req.user.name} logged in`);
                                return res.redirect('/');
                            });
                        })(req, res, next);
                    };

                    module.exports.logout = (req, res) => {
                        console.log(`User ${req.user.name} logged out`);
                        req.logout();
                        res.redirect('/');
                    };
                
            

Con esto ya tendremos la funcionalidad definida para cada una de las rutas de routes/auth.js.

Requiriendo Passport y Sesiones

Para lograr que un Usuario se mantenga logado deberemos tratar el tema de las Sesiones. Este no es un tema sencillo y requiere un procesamiento determinado que puede ser complicado. Afortunadamente existen un par de paquetes que nos ayudarán con esta tarea: Express-Session y Passport.

Instalaremos ambos paquetes con:

npm install -S express-session passport

Ahora deberemos integrar todo esto en nuestra aplicación Express!

Modificando app.js

Editaremos app.js con las siguientes modificaciones:

                
                    ...
                    const bodyParser = require('body-parser');
                    const session = require('express-session'); //<-- Nuevo
                    const passport = require('passport');       //<-- Nuevo

                    require('./server/models/db.js');
                    ...
                    app.use(express.static(path.join(__dirname, 'public')));
                    app.use(session({                           // <-- Nuevo
                        secret: 'keyboard cat',
                        resave: false,
                        saveUninitialized: false
                    }));
                    app.use(passport.initialize());             // <-- Nuevo
                    app.use(passport.session());                // <-- Nuevo

                    app.use('/', index);
                    app.use('/users', users);
                    app.use('/auth', auth);                     // <-- Nuevo
                    ...
                
            

Perfecto! Ya casi tenemos a Express listo para soportar Registro y Login de Usuarios. Sólo nos falta realizar la configuración de Passport, pero esto lo dejaremos para el próximo capítulo.

Nótese que hemos montado nuestro middleware auth encima del path /auth, esto quiere decir que todas las urls referentes a la Autenticación y Registro de Usuarios empezarán por ese path. Esto quiere decir que las url's serán:
  • auth/login.
  • auth/register.
  • auth/logout.

Recordad que podéis mirar el código desde aquí.

Si tienes alguna duda o sugerencia, no dudes en participar!