Switch between persistent and non-persistent session based on user selection - node.js

I am trying to create a login feature for my web application using express-session as a session middleware and connect-mongo as persistent store. I was able to implement persistent session using the mongo store, before which, express-session supported in-memory session until users closed the browser.
I am providing a feature wherein, if the user, while logging in, selects a checkbox "Keep me signed in", creates a persistent session for n days, but if not, by default, the session should expire on closing the browser. I have lost the ability to clear session on browser exit now that I have implemented persistent store with connect-mongo.
How do I switch between both session approach for my feature.
Is it possible to clear session on browser exit in connect-mongo? If so how to I handle the browser event.
Is it practical to implement session based on user selection, and implement persistent store only if user chooses to keep him signed in?
Please suggest better option or one that I don't see yet.

I believe you confuse 2 different things.
express-session uses different stores to retain sessions on server side. It can be in-memory storage which is cleared out once the node process exits (not when a browser is closed) or it can be persistent storage on disk/in a database.
If you read connect-mongo README carefully you'll notice that it clears sessions from DB based on cookie's expiration date or if not set it will use ttl option you can provide (see here).
But this is on the server side and it doesn't affect the expiration date of the cookie which browsers respect.
A session cookie is a cookie that has no expiration date set, i.e. such cookie will be deleted by a browser when it's closed. Initially, you can set maxAge of a cookie using cookie.maxAge option that you pass to session method of express-session. You can use this value as a session expiration date for a user which selects "Keep me signed in" checkbox.
For users who don't select "Keep me signed in" you can adjust the cookie expiration dynamically by accessing it via req.session.cookie inside your endpoint where you have your user's sign-in logic:
req.session.cookie.expires = false
This info is also in express-session docs here.

Related

Node express server session management middleware?

I want to do only cookie based authentication for my app. No pwd or email need to be given.
It is like the guest user feature in some webapps (like discord). You can use the app like
a logged in user as long as you have that cookie (or local storage). I find this very seamless and I don't want to put up signup barrier to the visitors.
I want a middleware, which does the following :
If request does not have a session id, it has to create a new session (by adding new document in sessions collection in mongodb, and setting the field session_id with random string)
If the request has cookie, it has to parse the cookie and set in request object. Even better, it gets the session object from db and set it in request object.
Is there anything right out of the box that does this? Or any other ways to easily achieve this?
express-session with a mongodb data store will do that pretty much right out of the box. There are multiple session store options for mongodb here. One of them is even maintained by the mongodb team.
In a nutshell, express-session will check for an incoming session cookie. If one exists, it will look up the session ID in the session store and find the session object for that ID. If there is no cookie or the DB has no session for that ID, it will make sure there's a cookie and create a new session for it. That session will be available as req.session for that request for all request handlers and middleware downstream of the session middleware.
You will need to age away old sessions from mongodb because if you're not attaching any login to them, then lots of the sessions will get permanently orphaned either when the user never comes back to your site or when the user's cookie ages away. And, the same user from multiple devices will cause multiple separate sessions to be created (which is a by-product of the auto-session-creation and login-free design).

Session vs Cookie, what's the difference?

I have a question about Sessions and Cookies on Node regarding where they are stored and how they work.
To begin with, I understand the following to be true:
With a cookie, it is possible to specify how long it will store your data;
A session saves data while the browser is open;
Cookies are on the client side;
Session is on server side;
Then the following questions arise:
How does the browser and/or the server know that the user has already
logged in and does not need to log in again?
If the Session stays inside a cookie what's the difference?
Where are cookies stored? In the web browser?
I use the (Blackberry?) passport (browser?) but it does everything by itself. I want to better understand how it works behind the scenes.
My affirmations can be wrong. You can correct me, but please explain to me.
Regarding what you understand to be true:
Yes, when setting a cookie, you can specify how long it will persist. In the article HTTP Cookies in Node.js, see the section entitled
"Adding Cookie with expiration Time".
Yes, data can be stored in a
session if it is explicitly placed there by application code. Your server software may also use it to store other information. Here
is a nice short YouTube video on node.js sessions.
Cookies are stored in a file on your computer which is managed by your web
browser, so again, correct. Here's a nice article that explains in more detail: Cookies - Information that websites store on your computer.
As to your other questions:
How does the browser and/or the server know that the user has already
logged in and does not need to log in again?
It generally knows this by storing a cookie in your browser whose value is some sort of session ID that acts as an authentication token. When you are successfully authenticated, it will store a cookie and send this cookie's value as an HTTP header or as part of the URL string, etc. each time you make a request to the server. This token is stored on the server with some sort of expiration time, usually something like 15-60 minutes. The expiration timer is reset to zero with each successful request. If session timeout is 30 minutes for example, the token will be invalid after no request is made within 30 minutes. Therefore, if you walk away from your computer for an hour and try to access another page, you will likely be told you need to log in again.
If the Session stays inside a cookie what's the difference?
As I stated in the answer to the previous question, an authentication token is generally stored as a cookie and sent with each request. It's good to use over and over until the session times out.
So, the difference is: A session is stored on the server. A cookie is stored as a file on your computer by your browser. A session cookie is stored on your computer which is used by the server to track individual user sessions.
Where are cookies stored? In the web browser?
Yes, as stated above, cookies are stored in a file on your computer which is managed by your web browser. See the article I linked to above for more detail.
First off, some general facts.
A cookie is stored in the browser and then sent back to the target server with every request to that server.
A cookie can either contain actual state data (such as backgroundColor=blue) or it can just contain a token that only means something to the server.
Whoever sets a cookie decides how long they want it to last before it "expires". If the server sets the cookie (as cookies can also be set from within Javascript in the web page), then the server decides how long they want the cookie to last.
A server session consists of the server creating a unique token and putting that in a cookie that it sets for that browser. In parallel, it also creates a session object that is stored on the server and it creates a means of associating the token with a particular session object such that when a request comes in and it has a particular token in it, the server can find the corresponding session object.
Note, sessions don't have to use cookies. They can also put a session id in the URL itself and that is occasionally used, but isn't very popular for a variety of reasons.
How does browse and / or server know that the user has already logged in and does not need to log in again?
A server can consider a browser to be already logged in if it finds an appropriate cookie in the incoming request and if it finds an associated session object in the server-side session store and if that session object is both logged in and not expired.
If the Session stays inside the cookie why is this difference?
Usually, when using server-side sessions, all that's in the cookie is a unique token - not any of the actual session data.
Where is the cookie stored? In our browser?
Yes, it's stored on your hard drive by the browser and then sent as an http header along with every request to the server that the cookie is associated with.

How do I know when a session has expired?

I'm learning to use the "client-sessions" package in Node.js, with Express. Everything seems to be working well. But I'm wondering, is there is a way to have it call a function if a session expires?
I'm setting things up so that the session only stores a unique ID. Then outside of the session I store all the user data and anything else I need. That way it keeps my cookies and session info very small. But I want to know when a session has expired so that I can clear any info that doesn't need to be kept after the session is gone.
But I have not been able to find any details on how to do this. Am I thinking about this in the wrong way? If I store everything in the session it will try to store it all in the cookie as well won't it?
thanks in advance.
Making my comments into an answer since it appears to have helped you solve your issue...
If you use a session manager like express-session that only stores a session ID in the browser cookie and keeps a session object server-side in the session store, then you can just store your data directly in the session object and when the session expires, the session manager will just automatically clean up the session (including your data in the session). Then, you don't have to worry about when it expires as things are just managed for you automatically.
express-session has the ability to look up a given session in the session store.get(sessionID, callback) where store is the session store object you're using. To use that, you need to have previously saved the sessionID for a given user that you want to look up.

In Express.js, is it safe to store any data in sessions?

I'm used to working solely with cookies.
With cookies, I would save a username and hash and perform a database query on each pageload, to ensure that the user has the correct password. I was about to do the same thing with sessions, when it occurred to me that sessions are not editable by the user.
Theoretically, I could say:
req.session.authenticated = true
and just test to see if the user has been authenticated, without rechecking if the password was correct.
Is this safe to do?
Or is it necessary to store the username and hash?
P.S. I'm using Express 4.8.6 with express-session 1.7.6
express-session doesn't store any working data in the cookies. Instead it stores a uuid in the cookie, and then matches that uuid to data in your session store (defaults to in-memory).
So if I visit your site, you'll give me a cookie containing 23949324. Any data that you assign to my session will be stored somewhere not in my browser, my cookie remains 23949324. Redis is a common session store.
You can do req.session.creditcard = "4186xxxxxxxxxxx2" and that's technically safe, at least in the realm of cookies. Realistically, you probably shouldn't be storing credit card data plaintext in your session store.
If you'd like persistant sessions I'd recommend express-sessions.

Node/Express: Session Expire Event?

On asp.net, we have a session expire event. I'm using node.js with express.js and the default memory store for sessions. Every time I restart node, the sessions are lost. Ideally, I'd like to save the sessions to the db (can't use redis).
Is there a session expire event?
If you want to save the sessions to a database which isn't Redis, there are more solutions: https://github.com/senchalabs/connect/wiki (check the Session Stores section).
As far as I know there isn't such an event for cookie/session expiration (I've looked at the code for Connect and didn't find such a feature).
Also if you don't want to use sessions with a database at all, the are several modules for that (storing sessions in cookies, encrypted):
https://github.com/jpallen/connect-cookie-session
https://github.com/ciaranj/express-session-cookie

Resources