Search code examples
node.jsexpressexpress-4

Using Express 4 how to redirect to my own route without losing req and response data?


I have my application structured with 3 Routes (api, admin, default). Each lives in there own file and has it's own middleware and exports a Route. The problem I am facing is when I want to forward to another route that lives on a different router. Essentially I want to call the same function so that I am not serving up the same view from multiple locations.

I don't want to user res.redirect('/someplace') because I want to be able to pass the req and res objects on to the method.

|-app.js
|-routes
  |---admin.js
  |---api.js
  |---default.js

The routes are required and used in app.js as follows

app.use('/api', require('./routes/api')(passport);
app.use('/admin', require('./routes/admin')(passport);
app.use('/', require('./routes/default')(passport);

Inside of admin if have a situation where I need redirect to login and pass some data

// authenticates all routes for the admin router
router.use(function(req, res, next){
    if(req.isAuthenticated()){
        return next();
    }
    res.flashMessage.push('Session expired'); //is lost after redirect
    res.redirect('/login');
    //do I need to restructure my whole app so that I don't
    //have to call res.redirect('login')
});

Any ideas on how to structure this? Do I need to export every method and keep all of my routes in one router file? That doesn't very clean, but if the functions are somewhere else it may be too messy.


Solution

  • You can forward it by calling the next callback ,but only if you do not use any paths.

    app.use(function(req, res, next) {
        // ... api
        next();
    });
    
    app.use(function(req, res, next) {
        // ... admin
        next();
    });
    

    Another option is use * that will match all paths:

    app.use("*", function(req, res, next) {
        var path = req.path; // just example how it can be done
    
        if (path === "/api") {
           // ...
           path = "/admin";
        }
    
        if (path === "/admin") {
           // ...
        }
    });
    

    Edit:

    I don't think that express has something like next('/login'); ,so basically function that can forward a request to another path and I don't think that is right to have something like this. If a client ask for /admin you should send this particular page and not the page that is under /login. If you want to send back to a client the login page than just redirect it as you did it in your question. I understand that you want to keep the req, res ,but then is the problem in the proposal/structure of your webapp.