Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

route separation with express router and passing instances

So I'm trying to separate all my routes and organize them. I've manage to do that, but I face an issue. Using express 4, and the router I am having a problem passing an instance of something to a particular route. For example I want to pass passport to the login.js file. How would I do that? Am I doing this the correct way, or is there a better more cleaner solution?

//app.js

var express = require('express');
var passport = require('passport');
var app = express();

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

//routes.js

module.exports = function (app, passport) {
  app.use('/', require('./routes/index'));
  app.use('/', require('./routes/login')(passport));
  app.use('/', require('./routes/register')(passport));
};

//login.js

Here passport is undefined.

var express = require('express');
var router = express.Router();

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

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

module.exports = router;
like image 506
Daniel Avatar asked Aug 06 '14 03:08

Daniel


1 Answers

So there's two ways folks do this, and there's pros and cons to each.

Easiest is to have your passport config in a file of your own (i.e. where you setup all your passport strategies, etc), and that file exports the passport object after setting it up.

e.g.

/* in ./lib/passport.js */
module.exports = passport;

Then in some other file that needs it, you just require your passport file (code in there only gets called once, and the exported module is cached after that).

/* in some other file */
var passport = require('./lib/passport');

this has the advantage of simplicity, but a lot of folks feel (rightly so) that it's not quite as testable if you're doing unit tests, b/c you can't isolate the file under test as easily, etc.

so in that case, each module file will export a function which takes its dependencies in through a function. For example,

/* in your router file */
var router = require('express').Router();

var loginRoutes = function(passport){
    router.post('/login', passport.authenticate('local-login', { 
        successRedirect: '/profile',
        failureRedirect: '/login'
        }));
    return router;
};

module.exports = loginRoutes;

then wherever you're pulling the routes into the app, that process just requires the route file and calls the function, passing it the passport instance. which looks like what you did in routes.js.

like image 69
Paul Avatar answered Oct 18 '22 15:10

Paul