24

http://www.javascriptkit.com/javatutors/cookie.shtml

Session-only cookies, on the other hand, stores information in the browser memory, and is available for the duration of the browser session. In other words, the data stored inside a session cookie is available from the time of storage until the browser is closed. Moving from page to page during this time does not erase the data.

How can I achieve this using Express.js?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alfred
  • 60,935
  • 33
  • 147
  • 186

6 Answers6

66

First off, that website is a horrible place to go.

Now on to the question.

What sessions actually are:

  • Data is stored on the server side.
  • A cookie is issued which contains an ID.
  • This ID gets send back to the server on every request, due to the fact that the browser sends the cookies.
  • Now the server can re-associate the ID in the cookie - commonly called Session ID or short SID - with the session data stored on the server.

Express.js has support for sessions built in.

What the example shows:

  • Setting up the Express.js middleware
  • Using a third-party store for saving the session data, in this case Redis (which IMO is overkill for your problem atm)

Installing Redis requires quite some work, but it's also possible to use Express.js's built-in memory store:

var express = require('express');
var app = express.createServer();

var MemoryStore = require('connect/middleware/session/memory');
app.use(express.bodyDecoder());
app.use(express.cookieDecoder());
app.use(express.session({ store: new MemoryStore({ reapInterval: 60000 * 10 }) }));

app.get('/', function(req, res){
    req.session.visitCount = req.session.visitCount ? req.session.visitCount + 1 : 1;
    res.send('You have visited this page ' + req.session.visitCount + ' times');
});

app.listen(4000);

This will simply keep track of how many times you visited the page, closed your browser and re-opend. The counts will still be there.

You can find more on the options of the MemoryStore, like maximum life time of a session, etc. here.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ivo Wetzel
  • 46,459
  • 16
  • 98
  • 112
  • A lot of sites have session only cookies. Even gmail? The 'stay signed' check box is session only? Because I want the user to be logged out when the browser has closed. Because it can be accessed on shared pc and people can forget to press the logout button? I would like to create a 'stay signed in' checkbox? so have both type of sessions. Is this possible? Many thanks. – Alfred Dec 06 '10 at 22:26
  • 1
    P.S: your snippet is not session only cookie, because when you close cooke it will remember count instead setting count to zero again. But I think I know how to solve this problem. – Alfred Dec 06 '10 at 22:36
  • @Ivo, the question was about session only cookie! – Ustaman Sangat Jan 12 '12 at 16:09
  • 1
    in Ivo's defense, I never heard the term "session-only" to describe the cookie. Sessions do generally refer to server-maintained information keyed by a generated cookie value, as he described, no? Is the question different from "how do I expire a cookie when the browser closes"? – grantwparks Apr 14 '12 at 07:01
  • This is not what he asked. You can have all of your session lying on a signed cookie in a browser... the amount of confusion on NodeJS packages that supposedly do this - but don't actually - is insane - and it's a testament to the lack of basic knowledge from most NodeJS developers – João Antunes Nov 28 '19 at 15:33
  • From [express-sesssion's readme](https://www.npmjs.com/package/express-session): "Warning The default server-side session storage, `MemoryStore`, is purposely not designed for a production environment. It will leak memory under most conditions, does not scale past a single process, and is meant for debugging and developing. For a list of stores, see compatible session stores." – Mythos Oct 15 '21 at 00:18
11

The following is what I wanted (sort of). When I close browser the information is gone.

var express = require('express');
var app = express.createServer();

var MemoryStore = require('connect/middleware/session/memory');
app.use(express.bodyDecoder());
app.use(express.cookieDecoder());

app.get('/remember', function(req, res) {
    res.cookie('rememberme', 'yes', { expires: new Date() - 1, httpOnly: true });
});

app.get('/', function(req, res){
    res.send('remember: ' + req.cookies.rememberme);
});

app.listen(4000, '127.0.0.1');
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alfred
  • 60,935
  • 33
  • 147
  • 186
7
app.use(express.session({cookie: { path: '/', httpOnly: true, maxAge: null }, secret:'eeuqram'}));

The above works on IE8, Firefox and Chrome. The important piece is maxAge:null

Ustaman Sangat
  • 1,505
  • 1
  • 14
  • 26
2
app.get('/remember', function(req, res) {
   res.cookie('rememberme', 'yes', { expires: 0, httpOnly: true });
 });

This will set session cookie. On browser close it will be erased!

Raja
  • 3,477
  • 12
  • 47
  • 89
1

Below is the updated code for Alfred's answer (session using Express.js).

    var express = require('express');
    var app = express.createServer();

    var MemoryStore = require('/home/node/node_modules/connect/lib/middleware/session/memory');
    app.use(express.bodyParser());
    app.use(express.cookieParser());
    app.use(express.session({
        key: 'some-key',
        secret: 'some-We1rD sEEEEEcret!',
        store: new MemoryStore({ reapInterval: 60000 * 10 })
    }));

   app.get('/', function(req, res) {
       req.session.visitCount = req.session.visitCount ? req.session.visitCount + 1 : 1;
       res.send('You have visited this page ' + req.session.visitCount + ' times');
   });

   app.listen(4000);
Community
  • 1
  • 1
Raja
  • 3,477
  • 12
  • 47
  • 89
0

I know this is an old question but I'm adding an answer since all answers here seem to be either outdated, have security flaws or are just plain wrong.

As of now, express uses the MemoryStore by default, you don't need to explicitly handle that.

Also, as of now, the express-session's official readme page has a stark warning at the beginning to not use MemoryStore as the session store for production, quoting:

Warning The default server-side session storage, MemoryStore, is purposely not designed for a production environment. It will leak memory under most conditions, does not scale past a single process, and is meant for debugging and developing.
For a list of stores, see compatible session stores.

Here's a simple solution with connect-mongodb-session if you want to use MongoDBStore for session storage:

import express from 'express';
import session from 'express-session';
import ConnectMongoDbSession from 'connect-mongodb-session';

const app = express();
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(session({
  secret: < COOKIE_SECRET >,
  name: 'sessionId', // Don't use the default name, see http://expressjs.com/en/advanced/best-practice-security.html
  cookie: {
    httpOnly: true,
    secure: true, // Remove this if you're not using HTTPS, but it will be a massive security flaw
    sameSite: 'strict',
  },
  store: getStore(),

  // Boilerplate options, see:
  // * https://www.npmjs.com/package/express-session#resave
  // * https://www.npmjs.com/package/express-session#saveuninitialized
  resave: true,
  saveUninitialized: true,
}));

function getStore() {
  const MongoDBStore = ConnectMongoDbSession(session);

  const store = new MongoDBStore({
    uri: < DATABASE_URI >,
    collection: < SESSION_COLLECTION_NAME >,
    connectionOptions: {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    },
  });

  store.on('error', (error: any) => {
    console.error(error);
  });

  return store;
}
Mythos
  • 1,378
  • 1
  • 8
  • 21