Categories
express node.js prototype serialization session

Why would an object’s prototype be forgotten?

Introduction

So I am building a website with node.js, express, express-session, and sequelize.js. Once a user logs in, an instance of the Sequelize model User is created. In my route for user log-in (/auth/login), I have:

var user = (await User.findAll(
{where: {
username: username
}}))[0];

and I few lines down I assign that user to the session.

req.session.user = user;

And then I can persist any changes by simply calling the save method of req.session.user:

await req.session.user.save();

And indeed, if I add this line next:

console.log(Object.getPrototypeOf(req.session.user));

the output is [object SequelizeInstance:User]. So far so good.

Here is the problem

In another route (/users/myaccount/edit-bio) I am able to access the values of req.session.user. That is, the output of

console.log(req.session.user.username);

is seanletendre, as expected. But now when I call

await req.session.user.save();

all I get is the error message:

UnhandledPromiseRejectionWarning: TypeError: req.session.user.save is not a function

“That is weird,” I thought, “isn’t this the same object?” To investigate, I add the line:

console.log(Object.getPrototypeOf(req.session.user));

just as I did in the log-in route. And what is the output? It is: [object Object]. So it seems that somehow the prototype of req.session.user gets forgotten. I don’t understand how this can be.

Is it possible to re-assign a prototype to a plain object?

Suspect A

Based on the comments to my question, I suspect that the prototype is lost when the session manager serializes req.session. It seems that, unlike I thought before,req.session does not point to the exact same session object for different requests. Each time a request ends, it serializes and stores req.session. Then upon receiving a new request with a cookie designating it as part of the same session, the session object is fetch from the session store.

This is how my session middleware is setup:

var session = require('express-session');
//
// yada, yada, yada
//
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {secure: true}
}));

So what surprises me is that, even though I am using the default store MemoryStore, my sessions are still serialized.

My question now becomes: how can I prevent object serialization upon session store when using MemoryStore?