So I'm building a simple authentication application and I'm using express-sessions to do this. For the UI, I need to display in the nav-bar a button for logging in, if the user hasn't done so already, and a button for logging out if they are already logged in.

The problem is, I'm not sure how to store this state across all of my routes, without using the same code for each route. Currently I've got this on the index route, which works fine:

/* GET home page. */
router.get('/', function(req, res, next) {
  var logged_in = false;
  if (req.session.userId) {
    logged_in = true;
  res.render('general/index', { is_logged_in: logged_in});

And in the nav-bar I display the buttons dynamically like so:

<% if( is_logged_in){ %>
<li class="nav-item active">
<a class="nav-link" href="/users/logout">Logout<span class="sr-only">(current)</span></a>
<% } else { %>  
<li class="nav-item active">
<a class="nav-link" href="/login">Login<span class="sr-only">(current)</span></a>
<% } %>

But the problem is, I have to use the same code for each route if I want this to work for the nav-bar, which goes against DRY coding practices. How do I display this button dynamically without having to repeat the same bit of code on each route, checking if a user session ID exists? Do I set a global variable? I'm new to Express so all help appreciated. Thanks

1 Answers

spaceout On Best Solutions

You can setup a middleware to set the login status and use the res.locals for the lifetime of the request.

function checkLoggedIn(req, res, next) {
  var logged_in = false;
  if (req.session.userId) {
    res.locals.logged_in = true;

You can then mount it for all the routes or chain it for some routes:

// all routes after this middleware:

// chain it
app.get('/mypath', checkLoggedIn, (req, res) => { ... })

res.locals are available to view as well so you can do the following without passing during render.

// You can simply render

// logged_in variable is available to view
<% if(logged_in){ %>