Wednesday, 15 March 2017

Passing passport properly in router.use chain

I'm currently working on a data storage api and before I had the API built without authentication. The whole API was split into multiple files which each export a router object.

Now I'm in the process of adding passport authentication to all of the different API endpoints, but cannot figure out how to pass the passport object down the whole router stack, or should I even be doing that?

The file hierarchy is currently like this:

server.js
  routes.js
    frontendRoutes.js
      login.js
      other.js

In server js I'm passing the passport object to the routes file:

var routing = require('./backend/routers/routes.js')(passport);
app.use('/', routing);

In the routes.js I'm adding all the

module.exports = function(passport){

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

var frontendRouter = require('./frontendRouters/frontend.js')(passport);
var APIRouter = require('./apiRouters/APIRouter.js');
var appController = require('./appRouters/apps.js');

//load frontend routers
router.use('/',  frontendRouter);

//load API routing
router.use('/API', APIRouter);

//load Apps routing
router.use('/apps', appController);

return router;
};

And in frontend I have a couple of extra routers:

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


var dataImporter = require('./dataImporter.js');
var login = require('./login.js');

module.exports = function(passport){

//serve HTML content 
router.get('/', function(req, res) {
    //serve the login page here
    console.log("hello");
    res.sendfile('./frontend/views/index.html');
});


//serve dataManager
router.use('/dataImporter', dataImporter)(passport);

router.use('/login', login)(passport);

return router;

}

And finally in login I'm using the passport object:

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

var passport = require('passport');


module.exports = function(passport){

/* GET login page. */
router.get('/', function(req,res){
// Display the Login page with any flash message, if any

res.sendfile('./frontend/views/login.html');

});

/* Handle Login POST */
router.post('/', passport.authenticate('login', {
successRedirect: '/',
failureRedirect: '/test',
failureFlash : true 
}));

return router;
}

Now before I added the passport everythign was working fine, but now I'm getting the following error:

   C:\workspace\node_modules\express\lib\router\index.js:140
  var search = 1 + req.url.indexOf('?');
                          ^

TypeError: Cannot read property 'indexOf' of undefined
    at Function.handle (C:\workspace\node_modules\express\lib\router\index.js:140:27)
    at router (C:\workspace\node_modules\express\lib\router\index.js:46:12)
    at module.exports (C:\workspace\backend\routers\frontendRouters\frontend.js:30:43)
    at module.exports (C:\workspace\backend\routers\routes.js:19:62)
    at Object.<anonymous> (C:\workspace\server.js:103:53)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:394:7)
    at startup (bootstrap_node.js:149:9)
    at bootstrap_node.js:509:3
[nodemon] app crashed - waiting for file changes before starting...

So I have not figured out how to pass the passport object down the router chain properly(probably)? How should I pass the passport object to each router or is this a compeletely stupid architecture to do this?



via TeraTon

No comments:

Post a Comment