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-sessionAdd 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 },
}));| Option | Meaning |
|---|---|
secret | The key that signs the cookie so it cannot be forged |
resave: false | Do not save the session if it did not change |
saveUninitialized: false | Do not create a session until something is written to it |
cookie.httpOnly | The cookie is not available to scripts on the page |
cookie.maxAge | Lifetime 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.