I was trying to comprehend express-session from the docs and I am unable to get some points
Consider this code, which I found from a repo
app.use(session({
resave: true,
saveUninitialized: true,
secret: 'aaabbbccc',
store: new MongoStore({
url: MONGO_URI,
autoReconnect: true
})
}));
Now, I probably get what is happening here but still just to confirm
resave: true according to the doc will mean that it will force to save session back to the session even if it hasn't changed. Okay Cool? But why would someone force to save a session when it isn't changed and what difference will make it make?
saveUninitialized: true Here we are storing the session for non-logged in user as well?
And Finally if someone could explain this line of code as well (which I am unable to comprehend)
store: new MongoStore({
url: MONGO_URI,
autoReconnect: true
})
Moving on, In the above code, the author of the repo isn't storing the session in the cookie? and is just storing the cookie identifer?
And lastly, In the description they have mentioned/talked about cookie.httpOnly, cookie.expires and cookie.domain
Now, I understood their functionality but am unable comprehend their implemention, so if anyone could showcase implementation for any one of them?
These are my understandings. I might be wrong.
May be resave is used for certain storage driver to keep session alive!? I don't have anything in mind right now.
saveUninitialized is true means, a session will always be created. Experiment: Create a simple express server. Configure express-session and keep that value true. Don't create any session manually. Hit any endpoint of your server from browser. Open developer options and look for cookies. You will see a cookie has generated. Now, remove the cookie. Change the value to false and hit the endpoint again. No cookie will generate this time.
If you don't mention any store then all sessions will be stored in MemoryStore which is build only for development purpose. So in production you should always use some sort of persistent storage. There are a good numbers of storage options available.
Related
I'm quite new to OAuth and not sure what to do with the access token I receive from another party. Right now I'm using express session on https with secure and httpOnly settings. This works fine, until I upload an image on the same API server (which happens after I add a product). Everytime my server detects changes, the token I saved becomes undefined, this means that the user has to go through the whole OAuth process again.
Since I use MYSQL, is it possible to save the token information in the database (expiry, refreshtoken, accesstoken) linked to the user or is there a better way to save this data?
My setup is very basic, I have one API Server and one React app for front-end.
I receive the token information by making an API call with my own API to the other party, the response from this party is what I end up sending as cookies to the React app.
This is the session code I have right now:
app.use(
session({
secret: process.env.SESSION_SECRET,
name: "token",
cookie: {
secure: true,
httpOnly: true,
},
resave: true,
saveUninitialized: true,
})
);
For anyone that runs into the same problem, by default express session uses MemoryStore. I missed this when I was reading the documentation.
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.
To fix this, you can use either "cookie-session" or pick one of the stores from the documentation.
https://www.npmjs.com/package/express-session#compatible-session-stores
EDIT - Oct 22, 2017
There was more than one reason our sessions weren't persisting, I've had to change ourexpress-session options to this:
api.use(session({
secret: 'verysecretsecret',
resave: false,
saveUninitialized: false,
cookie: {
path: '/',
httpOnly: true,
domain: 'domain.dev',
maxAge: 1000 * 60 * 24
},
store: new MongoStore({ mongooseConnection: mongoose.connection, autoReconnect: true })
}));
Apparently domain: 'localhost' causes express-session to start a new session every single time someone starts a session and then refreshes/navigates away and back when you have a seperate node instance for session handling.
I've solved this issue by doing the following:
Added 127.0.0.1 domain.dev to my hosts file located in C:\Windows\System32\drivers\etc.
I needed a place to store sessions as per the answers given below, so we chose MongoDB. This meant I had to add the following to my express-session options:store: new MongoStore({ mongooseConnection: mongoose.connection, autoReconnect: true })
Added the httpOnly: true property to the express-session options.
Because we use jQuery for our ajax requests, I had to enable some settings in the front-end web app before making calls to the back-end:$.ajaxSetup({
xhrFields: { withCredentials: true },
crossDomain: true,
});
ORIGINAL POST
I'm currently working on a platform for which was decided to have the API running on port 3001 whilst the web application itself is running on port 3000. This decision was made to make monitoring traffic more easy.
Now, we're talking about express applications so we defaulted to using the express-session npm package. I was wondering if it's at all possible to save session data stored on the node instance running on port 3001 and be retrieved by the node instance running on port 3000 if that makes sense.
To elaborate, this is our user authentication flow:
User navigates to our web app running on port 3000.
User then signs in which sends a POST request to the API running on port 3001, session data is stored when the credentials are correct, response is sent so the web app knows the user is authenticated.
User refreshes the page or comes back to the web app after closing their browser so web app loses authenticated state. So on load it always sends a GET request to the API on port 3001 to check if there's session data available, which would mean that user is logged in, so we can let the web app know user is authenticated.
(If my train of thought is at fault here, please let me know)
The problem is that express-session doesn't seem to be working when doing this.
I've enabled CORS so the web app is able to send requests to the API. And this is what the express-session configuration looks like:
api.use(session({
secret: 'verysecretsecret',
resave: false,
saveUninitialized: false,
cookie: {
path: '/',
domain: 'localhost',
maxAge: 1000 * 60 * 24
}
}));
Preferably help me solve this problem without using something like Redis, I'd simply like to know if solving this problem is possible using just express-session and node.
Preferably help me solve this problem without using something like Redis
You want us to help you solve this problem preferably without using the right tool for the job.
Without Redis you will need to use some other database. Without "something like Redis" (i.e. without a database) you will need to implement some other way to handle something that is a book example use case for a database.
And if you're going to use a database then using a database like Redis or Memcached is most reasonable for the sort of things where you need fast access to the data on pretty much every request. If you use a slower database than that, your application's performance will suffer tremendously.
I'd simply like to know if solving this problem is possible using just express-session and node.
Yes. Especially when you use express-session with Redis, as is advised in the documentation of express-session module:
https://github.com/expressjs/session#session-store-implementation
If all of your instances work on the same machine then you may be able to use a database like SQLite that stores the data in the filesystem, but even when all of your instances are on the same box, my advice would be still to use Redis as it will be much simpler and more performant, and in the case when you need to scale out it will be very easy to do.
Also if all of your session data can fit in a cookie without problems, then you can use this module:
https://www.npmjs.com/package/cookie-session
that would store all of the session data in a cookie. (Thanks to Robert Klep for pointing it out in the comments.)
app.use(session({
secret: "testing credentials",
store: sessionStore,
resave: true,
saveUninitialized: true,
cookie : {
httpOnly: true,
//secure: true,
maxAge : 60 * 60 * 1000
}
}));
I'm working on some security problems on my newly developed website. And after done some research online, if secure=true is set, then it will be more secure. However,
If set secure: true, then information inside session will lose every time when the user send another request. Is there a way to solve this problem? If doesn't include "secure: true" in the cookie: , then the session will last for that maxAge.
If a cookie is set with the secure flag, it will only be sent to the server by the browser over https, and not plain http. This should be the default for production environments.
However, when developing an app, you probably use plain http on your dev machine. If you set your session cookie as secure in this case (using plain http), the server will never receive it, and you will experience a new empty session on each request.
So in short, you should only set the cookie as secure if you are using https (that is, in later stages of your development pipeline, and definitely in production).
On another note, if you set maxAge, the cookie will be persisted, which is not the best practice for session cookies. Without maxAge, the cookie will be kept until the user closes the browser and not normally persisted to disk, which is the correct behaviour for session cookies.
The session middleware for Express provides several configurable options.
resave: 'Forces the session to be saved back to the session store, even if the session was never modified during the request.'
saveUninitialized: 'Forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified.'
It appears that both options are for saving unmodified sessions. What's the difference?
I thought I would start off with a basic answer, my bit of understanding so far, and improve it together. Important question been 'dead' for too long.
From this I understand the difference is:
(Unmodified 'state' is different to uninitialized state)
resave: For any request made
Nothing in the session needs to change (no login etc).
Change of session required (logged in)
"Forces session to be saved even when unmodified"
saveUninitialized: Is about the state of the session, if its still in the uninitialized state.
Not modified only, nothing in the session needs to change (no login etc).
"Forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified."
Basically, a session is saved in the store only when it is modified; if you add, delete or edit a session cookie (eg: req.session.test = 'some value'). If you want all the sessions to be saved in store, even if they don't have any modifications go with saveUninitialized: true.
Now, re-saving also happens only when session variables/cookies changes. If you want to save then always go ahead with resave: true
I am new to MEAN stack, presently the mean stack is inserting sessions to mongodb:
app.use(session({
saveUninitialized: true,
resave: true,
//cookie: { maxAge: 600 },
secret: config.sessionSecret,
store: newmongoStore({
db: db.connection.db,
collection: config.sessionCollection
})
}));
But I want to save some custom variables in that session & access them across requests, I did not get how to save it in session. Let's say I want to save mydata in session, I saw some examples & tried like:
req.session.mydata = 'projectdata';
req.session.cookie.mydata = 'projectdata';
Both are not working. Also I want to update maxAge variable on every request to server side, how to do it? Kindly help me.
Better use Token based sessions, It will help you making you API universal ie, You can also use the same API for mobile applications.
Try implementing Token Based Authentication using psJwt.
You will find good articles for this on scotch.io and on Plural sight.