When to use saveUninitialized and resave in express-session
Asked Answered
R

6

97

I am newbie with the MEAN stack. I read the express-session github doc but there are some options which are unclear to me. Those options are saveUninitialized and resave.

Can anyone please explain with examples what are the advatanges of using saveUninitialized and resave, and what will the effect be if we change the boolean values in those options.

Syntax:-

app.use(session({
  resave: false,
  saveUninitialized: true,
}))
Rosie answered 2/11, 2016 at 13:39 Comment(0)
P
213

Let's assume that sessions are enabled globally (for all requests).

When a client makes an HTTP request, and that request doesn't contain a session cookie, a new session will be created by express-session. Creating a new session does a few things:

  • generate a unique session id
  • store that session id in a session cookie (so subsequent requests made by the client can be identified)
  • create an empty session object, as req.session
  • depending on the value of saveUninitialized, at the end of the request, the session object will be stored in the session store (which is generally some sort of database)

If during the lifetime of the request the session object isn't modified then, at the end of the request and when saveUninitialized is false, the (still empty, because unmodified) session object will not be stored in the session store.

The reasoning behind this is that this will prevent a lot of empty session objects being stored in the session store. Since there's nothing useful to store, the session is "forgotten" at the end of the request.

When do you want to enable this? When you want to be able to identify recurring visitors, for example. You'd be able to recognize such a visitor because they send the session cookie containing the unique id.

About resave: this may have to be enabled for session stores that don't support the "touch" command. What this does is tell the session store that a particular session is still active, which is necessary because some stores will delete idle (unused) sessions after some time.

If a session store driver doesn't implement the touch command, then you should enable resave so that even when a session wasn't changed during a request, it is still updated in the store (thereby marking it active).

So it entirely depends on the session store that you're using if you need to enable this option or not.

Painterly answered 3/11, 2016 at 7:38 Comment(10)
I have some doubts, Can we talk, it will help me a lot?Factor
@SurajJain shoot me an e-mail on robert AT klep DOT name :DPainterly
This is a great answer. Thanks for taking the time to write it.Vodka
What is a "touch" command? Is this session store you are talking about on the client side or server side?Beatrisbeatrisa
@Beatrisbeatrisa the touch command is documented here: github.com/expressjs/session#sessiontouchPainterly
Is resave needed for Redis?Lightless
@ROMS I don't think so.Painterly
11/10 for the answerToga
Great answer, I was having troubles understanding what they did but this absolutely cleared it up!Hetaera
Also, you may be interested in rolling options, as it keeps session cookie's maxAge updated for initialised session.Oscular
D
41

One thing to note is that if you set saveUninitialized to false, the session cookie will not be set on the browser unless the session is modified. That behavior may be implied but it was not clear to me when I was first reading through the documentation.

Demandant answered 29/3, 2017 at 15:18 Comment(2)
Wow this seems to have helped me. Thanks. I was making a post request for a like button and I was saving a the req.sessionID to the DB. Anyways whenever I clicked the button I got a new req.SessionID. It was a scary hour. anyways. when I did the handler for post request I added req.session.liked = id and now I am not getting new session ids. Hopefully this fixed my problem.Lalia
But what if the 'saveUninitialized' is set to "TRUE' but the session is not modified. I understand that the session will be saved in the store, but does a session cookie get set?Takishatakken
I
14

resave: It basically means that for every request to the server, it reset the session cookie. Even if the request was from the same user or browser and the session was never modified during the request.

saveUninitialized: When an empty session object is created and no properties are set, it is the uninitialized state. So, setting saveUninitialized to false will not save the session if it is not modified.

The default value of both resave and saveUninitialized is true, but using the default is deprecated. So, set the appropriate value according to the use case.

Ironware answered 1/6, 2021 at 7:22 Comment(0)
S
6
  1. Uninitialised = false
    It means that Your session is only Stored into your storage, when any of the Property is modified in req.session
  2. Uninitialised = true
    It means that Your session will be stored into your storage Everytime for request. It will not depend on the modification of req.session.
  3. resave = true
    It means when the modification is performed on the session it will re write the req.session.cookie object.
  4. resave = false
    It will not rewrite the req.session.cookie object. the initial req.session.cookie remains as it is.
Saratov answered 9/2, 2022 at 13:4 Comment(0)
S
2

I came to one conclusion:

1.When you set saveUninitialized to false, and if your created Session Object isn't modified i.e left empty, then you won't be able to see connect.sid on your browser cookies. This eventually forces your store not to store the session object because it hasn't been modified i.e left uninitialized. And vice versa for true.

For eg:

const express = require('express');
const dotenv = require("dotenv").config();
const app = express();
const session = require("express-session");
app.use(session({
  secret:"cat",
  resave:false,
  saveUninitialized:false,
  cookie:{httpOnly:true}
}));
app.get('/login',(req,res)=>{
  // req.session.user="sundar";
  // req.session.admin=true;
  console.log(req.sessionID);
  res.send(req.session.user);
})

app.post("/upload",(req,res)=>{
  console.log(req.session);
  if (req.session.user === "sundar") {
    res.send("uploaded" + req.session.user)
  }else{
    res.send("failed");
  }
  
})

app.listen(process.env.PORT, () => {
  console.log(`Listening on http://localhost:${process.env.PORT}`);
});

In this example if you hit /login from postman or browser and if you look at cookies, you won't be able to see connect.id because created session object isn't modified.

But if you modify /login as:

app.get('/login',(req,res)=>{
   req.session.user="sundar";
   req.session.admin=true;
/* here we modified session object by adding user and admin properties to object created */
  res.send(req.session.user);
})

Thus you can see connect.id cookie being set at browser or postman cookies section. This also means if you have a store connected with your session middleware, now your session will be stored at the store.

  1. If you set resave to true,then for each request your session-cookie will be reset each time. Ref : click here to read
Serb answered 31/7, 2021 at 12:56 Comment(1)
Just so others know you don't have to say res.send(req.session.user), just send your res.send as normal, just simply changing req.session.variable is enough for it to trigger the change.Sumerian
A
0

on saveUninitialized set true server will provide the browser with session cookie as well as save it in its memory, even there is no modification you have done in the session object. but when the later field is set false server will provide the session cookie only when you modify the session object, if you already have the session cookie then no worries!!

Altar answered 8/4, 2021 at 11:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.