Using react-router and express with authentication via Passport.js - possible?

afithings picture afithings · Jun 12, 2015 · Viewed 10k times · Source

So I'm working on a project that incorporates React, Express.js+Passport and Webpack. I understand the concept of pushing everything to a 'master' React component via react-router, then letting it hash out what gets displayed for the given route. That would work great here, I think. To be upfront, I am new to React.

My concerns are:

1) Can I/how can I still use Passport to authenticate my routes? If I understand react-router correctly, I'll have one route in my express app.js file, pointing to, say, a React component named <Application/>. However, Passport needs router.get('/myroute', isAuthenticated, callback) to check the session. Is it still possible to do so with react-router?

2) Furthermore, if this is possible, how do I pass values from the route in Express into my views, in React? I know in a typical view, I could use <%= user %> or {{user}} if I passed that from my route. Is that possible here?

Answer

shadeglare picture shadeglare · Jun 17, 2015

Split a view rendering path from API paths. After all you can set the authentication logic into api calls.

//Auth check middleware
function isAuth(req, res, next) {...}

//API routes
app.post("api/users/login", function() {...});
app.post("api/users/logout", function() {...});
app.get("api/purchases", isAuth, function() {...});
//and so on...

//Wild card view render route
app.use(function(req, res) {
  var router = Router.create({
    onAbort: function(options) {...},
    onError: function(error) {...},
    routes: //your react routes
    location: req.url
  });
  router.run(function(Handler) {
    res.set("Content-Type", "text/html");
    res.send(React.renderToString(<Handler/>));
  });
});

So you have to solve how you're going to pass server side rendered data in views to a client side (choose your isomorphic data transferring technique).

You can also create views and the redirection logic on a client side only and firstly render react components in an "awaiting" state that will be resolved on a client after a component will be mounted (check auth state via an API call).