Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Route separation in express routing with passing passport instance

Tags:

I'm trying to add user-login module to an existing app in node. It is using separate route files for each module and one main route file to use all the child routes which is ultimately used in server.js When I try to pass passport instance to the user route, it gives me error as passport is not defined. Here is my app code and structure:

app
    views
        user
            index.ejs
            login.ejs
            signup.ejs
            profile.ejs
    routes
        docs
            index.js
        user
            index.js
        index.js
    config
        passport.js

    server.js

server.js

const express = require('express')
    const app = express()
    const path = require('path')
    const bodyParser = require('body-parser')
    const cookieParser = require('cookie-parser')
    const passport = require('passport')
    const flash = require('connect-flash')
    const session = require('express-session')

    const routes = require('./routes/')

    const port = process.env.PORT || 3000;

    app.use(express.static(path.join(__dirname, 'public')));

    require('./config/passport')(passport);

    app.use(bodyParser.urlencoded({
        extended: true
    }));

    app.use(cookieParser());
    app.use(bodyParser.json());

    app.set('view engine', 'ejs');
    app.set('views', path.join(__dirname, 'views'));


    app.use(session({ secret: '********' })); 
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(flash());

    app.use('/', routes)(app,passport);

    const server = app.listen(port, function(){
      console.log('Server listening on port '+port);
    });

config/passport.js

var LocalStrategy = require('passport-local').Strategy;
const sql = require('mssql')
const bcrypt = require('bcrypt-nodejs')

module.exports = function(passport) {


    passport.serializeUser(function(user, done) {
        done(null, user);
    });

    passport.deserializeUser(function (username, done) {
        done(null,username);
    });


    passport.use('local-signup', new LocalStrategy({
        usernameField : 'email',
        passwordField : 'password',
        passReqToCallback : true 
    },
    function(req, email, password, done) {
        process.nextTick(function() {


        var strSQL = "SELECT count(id) as uCount FROM <tbl> WHERE username = '"+email+"'";
        var cb1 = function(err,recordset){
            if(recordset[0].uCount>0){
                return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
            } else{
                var strSQL1 = "INSERT INTO <tbl>(username, password) VALUES('"+email+"','"+generateHash(password)+"')";
                var cb2 = function(err,recordset){
                    return done(null, recordset,req.flash('signupMessage', 'Email registered successfully.'));
                };
                executeQuery(strSQL1,'INSERTION','<tbl>',cb2);
            }
        };
        executeSelection(strSQL,'SELECTION','<tbl>',cb1);
        });

    }));

    passport.use('local-login', new LocalStrategy({
        usernameField : 'email',
        passwordField : 'password',
        passReqToCallback : true
    },
    function(req, email, password, done) { 

        var strSQL = "SELECT a.count, id, username, password FROM <tbl> c , (SELECT COUNT(dbid) count FROM <tbl> b WHERE b.username = '"+email+"' ) a WHERE c.username = '"+email+"'";
        var cb1 = function(err,recordset){
            if(recordset[0].uCount <= 0){
                return done(null, false, req.flash('loginMessage', 'No user found.'));
            } 

            if (!validPassword(password,recordset[0].password))
                return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); 

            return done(null, recordset[0]);
        };
        executeSelection(strSQL,'SELECTION','<tbl>',cb1);

    }));

};

executeSelection = function(strSQL, operationType, tableName, cb){
    var request = new sql.Request(connection);

    request.query(strSQL,function(err,recordset) {
        if(err){
            logger.error('ERROR in '+operationType+' ON '+tableName+': '+err);
        }
        logger.info(operationType+' ON '+tableName+' successful!');
        cb(err,recordset);
    });

};

executeQuery = function(strSQL, operationType, tableName, cb,validateClient) {
    var request = new sql.Request(connection);
    request.query(strSQL,function(err, recordset) {
        if(err){
            logger.error('ERROR in '+operationType+' ON '+tableName+': '+err);
        }
        logger.info(operationType+' ON '+tableName+' successful!');
        if(cb){
            cb(validateClient);
        }
    });
};

generatePasswordHash = function(password) {
    return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};

validatePassword = function(curPass, dbPass) {
    return bcrypt.compareSync(curPass, dbPass);
};

routes/index.js

const mainroute = require('express').Router()

    /* ---- other existing routes included ---- */
    const r_docs = require('./docs')
    const r_user = require('./user')    /*my custom route*/

    /* ---- all other routes ---- */
    mainroute.use('/docs', r_docs);
    mainroute.use('/user', r_user)(app, passport);      /*my custom route*/

    mainroute.get('/', function(req, res){
      res.render('home');
    });

    module.exports = function(app, passport){
        mainroute;
    }

routes/user/index.js

const express = require('express')
    const router = express.Router()

    router.get('/', function(req, res) {
        res.render('user/index.ejs');
    });

    router.get('/login', function(req, res) {
        res.render('user/login.ejs', { message: req.flash('loginMessage') }); 
    });

    // process the login form
    router.post('/login', passport.authenticate('local-login', {
        successRedirect : '/profile',
        failureRedirect : '/login',
        failureFlash : true
    }));

    router.get('/signup', function(req, res) {
        res.render('user/signup.ejs', { message: req.flash('signupMessage') });
    });

    router.post('/signup', passport.authenticate('local-signup', {
        successRedirect : '/profile', 
        failureRedirect : '/signup',
        failureFlash : true 
    }));

    router.get('/profile', isLoggedIn, function(req, res) {
        res.render('user/profile.ejs', {
            user : req.user 
        });
    });

    router.get('/logout', function(req, res) {
        req.logout();
        res.redirect('/');
    });

    function isLoggedIn(req, res, next) {

        if (req.isAuthenticated())
            return next();

        res.redirect('/');
    }

    module.exports = function(app, passport) {
      router;
    }

Please suggest what am I doing wrong here. Thanks

like image 748
Aakash Jain Avatar asked Feb 17 '17 10:02

Aakash Jain


People also ask

How do routes work in Express?

A route is a section of Express code that associates an HTTP verb ( GET , POST , PUT , DELETE , etc.), a URL path/pattern, and a function that is called to handle that pattern.

How do I nest a route in Express?

You can nest routers by attaching them as middleware on an other router, with or without params . You must pass {mergeParams: true} to the child router if you want to access the params from the parent router. Save this answer.

How do you create routes in an Express application?

The express. Router() function is used to create a new router object. This function is used when you want to create a new router object in your program to handle requests.

Which function tells what to do when a GET request at the given route is called?

app. get() is a function that tells the server what to do when a get request at the given route is called. It has a callback function (req, res) that listen to the incoming request req object and respond accordingly using res response object.


2 Answers

You should wrap your main and user routes to run their logic when you call them and at end return prepared route:

routes/index.js

module.exports = function(app, passport) {
  const mainroute = require('express').Router()

  /* ---- other existing routes included ---- */
  const r_docs = require('./docs');
  const r_user = require('./user'); /*my custom route*/

  /* ---- all other routes ---- */
  mainroute.use('/docs', r_docs);
  mainroute.use('/user', r_user)(app, passport); /*my custom route*/

  mainroute.get('/', function(req, res) {
    res.render('home');
  });

  return mainroute;
};

routes/user/index.js

module.exports = function(app, passport) {
  const express = require('express');
  const router = express.Router();

  router.get('/', function(req, res) {
    res.render('user/index.ejs');
  });

  router.get('/login', function(req, res) {
    res.render('user/login.ejs', {
      message: req.flash('loginMessage')
    });
  });

  // process the login form
  router.post('/login', passport.authenticate('local-login', {
    successRedirect: '/profile',
    failureRedirect: '/login',
    failureFlash: true
  }));

  router.get('/signup', function(req, res) {
    res.render('user/signup.ejs', {
      message: req.flash('signupMessage')
    });
  });

  router.post('/signup', passport.authenticate('local-signup', {
    successRedirect: '/profile',
    failureRedirect: '/signup',
    failureFlash: true
  }));

  router.get('/profile', isLoggedIn, function(req, res) {
    res.render('user/profile.ejs', {
      user: req.user
    });
  });

  router.get('/logout', function(req, res) {
    req.logout();
    res.redirect('/');
  });

  function isLoggedIn(req, res, next) {

    if (req.isAuthenticated())
      return next();

    res.redirect('/');
  }

  return router;
};
like image 161
dNitro Avatar answered Sep 21 '22 10:09

dNitro


You need to require it at the top of your user/index.js. Simply:

var passport = require('passport');

Then to make sure the user is authenticated:

router.get('/some/path', isLoggedIn, function(req, res) {
    var user          = req.user;
});

function isLoggedIn(req, res, next) {
    if (req.isAuthenticated())
        return next();

    res.redirect('/');
}
like image 34
andrea-f Avatar answered Sep 21 '22 10:09

andrea-f