Simple login page in nodejs using express and passport with mongodb Simple login page in nodejs using express and passport with mongodb express express

Simple login page in nodejs using express and passport with mongodb


Here is a simple setup using passport to login / logout the users:

On the main app.js file

/* Auth config  --------------------------------*/// @see http://frederiknakstad.com/authentication-in-single-page-applications-with-angular-js/var passport = require('passport');var User = require('./app/models/User'),passport.use(User.localStrategy);passport.serializeUser(User.serializeUser);passport.deserializeUser(User.deserializeUser);// Default session handling. Won't explain it as there are a lot of resources out thereapp.use(express.session({    secret: "mylittlesecret",    cookie: {maxAge: new Date(Date.now() + 3600000)}, // 1 hour    maxAge: new Date(Date.now() + 3600000), // 1 hour    store: new RedisStore(config.database.redis), // You can not use Redis }));// The important part. Must go AFTER the express session is initializedapp.use(passport.initialize());app.use(passport.session());// Set up your express routesvar auth = require('./app/controllers/authController.js');app.post('/auth/login', auth.login);app.post('/auth/logout', auth.logout);app.get('/auth/login/success', auth.loginSuccess);app.get('/auth/login/failure', auth.loginFailure);

On your user model (ej. app/models/User.js)

I'm using the passport-local module, which further simplifies the login logic:https://github.com/jaredhanson/passport-local

/* Your normal user model      ----------------------*/var mongoose = require('mongoose'),    ObjectId = mongoose.Schema.Types.ObjectId,    PassportLocalStrategy = require('passport-local').Strategy;var schema = new mongoose.Schema({    name: {type:String, required:true, trim:true},    email: {type:String, required: true, trim: true, lowercase:true, unique: true},    image: {type:String},    password: {type:String, required: true },    created: {type: Date, default: Date.now}});/* Auth properties      ---------------------------*//* (passport)           ---------------------------*/// This is your main login logicschema.statics.localStrategy = new PassportLocalStrategy({        usernameField: 'email',        passwordField: 'password',    },    // @see https://github.com/jaredhanson/passport-local    function (username, password, done){        var User = require('./User');        User.findOne({email: username}, function(err, user){            if (err) { return done(err); }            if (!user){                return done(null, false, { message: 'User not found.'} );            }            if (!user.validPassword(password)){                return done(null, false, { message: 'Incorrect password.'} );            }            // I'm specifying the fields that I want to save into the user's session            // *I don't want to save the password in the session            return done(null, {                id: user._id,                name: user.name,                image: user.image,                email: user.email,            });        });    });schema.methods.validPassword = function(password){    if (this.password == password){        return true;    }    return false;}schema.statics.serializeUser = function(user, done){    done(null, user);};schema.statics.deserializeUser = function(obj, done){    done(null, obj);};var model = mongoose.model('User', schema);exports = module.exports = model;

On app/controllers/authController.js

I'm using a single-page application, so I'm returning JSON on login / logout. If you wish to redirect to somewhere else, you will have to modify the "login success" and "login failure" functions (or call res.render(...) or whatever).

var passport = require('passport');var AuthController = {    // Login a user     login: passport.authenticate('local', {        successRedirect: '/auth/login/success',        failureRedirect: '/auth/login/failure'    }),    // on Login Success callback    loginSuccess: function(req, res){        res.json({            success: true,            user: req.session.passport.user        });    },    // on Login Failure callback    loginFailure: function(req, res){        res.json({            success:false,             message: 'Invalid username or password.'        });    },    // Log out a user       logout: function(req, res){        req.logout();        res.end();    },};exports = module.exports = AuthController;

Lastly, you should point your login form (which needs to have the method="post" attribute set) to /auth/login. On login success, the "loginSuccess" callback will be executed. On login failure, the "loginFailure" callback will be executed.

Edit:

You can create new users in your mongo database by executing something like:

// On your main app.js fileapp.post('/auth/register', auth.register);// On your authController.js file, as per the previous examplevar User = require('./app/models/User'); // The model we defined in the previous example    ...register: function(req, res){    User.create({name: req.body.name, email: req.body.email, password: req.body.password}, function(err){      if (err) {        console.log(err);        ... // Your register error logic here        res.redirect('/* Your error redirection path */');        return;      }      res.redirect('/* Your success redirection path */');     });},...

Then, point a registration form to /auth/register. I didn't validated the data, but you should validate it before trying to save the user.