Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Sessions and flash messages

HTTP does not remember earlier requests: each one reaches the server as if for the first time. A session is server-side storage for one visitor's data that lives between their requests. The browser gets only a cookie with the session number and sends it with every request, and the server finds the data by that number.

Installing and enabling

npm install express-session

Add the middleware in src/app.js before the routes:

// src/app.js
import session from 'express-session';
 
app.use(session({
  secret: 'replace-with-a-long-random-string',
  resave: false,
  saveUninitialized: false,
  cookie: { httpOnly: true, maxAge: 7 * 24 * 60 * 60 * 1000 },
}));
OptionMeaning
secretThe key that signs the cookie so it cannot be forged
resave: falseDo not save the session if it did not change
saveUninitialized: falseDo not create a session until something is written to it
cookie.httpOnlyThe cookie is not available to scripts on the page
cookie.maxAgeLifetime in milliseconds, here a week

Writing and reading

Once enabled, every request has a req.session object. You can write any simple data into it:

// src/app.js
app.get('/visits', (req, res) => {
  req.session.visits = (req.session.visits ?? 0) + 1;
  res.send(`You have opened this page ${req.session.visits} times`);
});

Refresh /visits and the number grows. Open the address in another browser and the count starts over: it has its own session.

Flash messages

A flash message is shown once — on the page after a redirect, for example "Post published". It is written to the session, and middleware moves it into the template and deletes it right away. Create src/middleware/flash.js:

// src/middleware/flash.js
export function flash(req, res, next) {
  res.locals.flash = req.session.flash;
  delete req.session.flash;
  next();
}

Add it after session(): app.use(flash). Now the controller only has to write the text before redirecting:

// src/controllers/postsController.js
export function store(req, res) {
  const id = Post.create(req.body);
  req.session.flash = 'Post published';
  res.redirect(`/posts/${id}`);
}

And the header views/partials/header.ejs prints the message if there is one:

<% if (locals.flash) { %>
  <p class="flash"><%= flash %></p>
<% } %>

After publishing, "Post published" appears above the post, and on refresh the message is gone.

Where the data is stored

By default express-session keeps sessions in the process memory: after a restart every visitor is forgotten, and this store is not suitable for a real server. A production application connects an external store — Redis or a database, for example — through a separate package passed in the store option.

Common mistake

Do not keep secret right in code that goes into Git: anyone who knows the key can forge any visitor's cookie. Move it into an environment variable — the configuration lesson shows how. In the example above the string is there only for clarity.

Thanks for reading!

Donate to the site — we work hard for you.