As the title sais, I need to set a upper limit for concurrent sessions per user for a web app to prevent account sharing.
I'm using local strategy in passportjs (on node platform) for authentication.
What is the best practice to do so? Is counting the number of login requests (where the sessions are being created) enough?
I ended up adding another field to the session's table for keeping track of user_ids.
At each login action which the sessions are being created, I query all the sessions for the current user and delete them if they are over the limit.
For each successful login, you will need to maintain a session record in your database. When someone attempts to login, you will need to query the database to count the number of active sessions.
Your idea of counting the number of login requests doesn't work for a few reasons:
If the server restarts, the count would be lost, whereas the users would still be authenticated.
It does not scale with multiple Node processes, as each Node process will have no way of communicating login attempts to other processes.
Related
For last few days I am working on improving app performance. What do you think about caching user data and permission in redis? In my case every time when user create post or try to upload file app check in database, if user exist and fetch user permission and role. My first idea was to put permission and user role in session but user can have multiple session on different device, so every time when user get ban or user permission change app need to update every user's session and as far as I know express-session do not support this kind of feature.
Unfortunately it's a very open question with no strict answer. But as an advice, I'd say Redis is perfect for storing user session altogether. Moving parts of the session would still require you to query the database (you get the session, you must query for user information, and also ping Redis for permissions & roles). So I think you should put all session data in one place, and the fastest would be Redis. It would also let you save that data so it's not entirely in the memory. There are also many ways to optimize it, like when to write the data (like every second) and so forth.
Querying Redis is extremely fast and efficient since you don't have any user to user relations, and most of the times you won't search on anything different than "get me that user session by id".
It's a very standard solution to put user session in Redis, if not the most often used one :) Good luck!
I want to make a simple app using MERN (Mongo, Express, React, Node), in which only one person will have to upload pics or write a blog; clients can only view in general. So, I want to create one user authentication. How can I achieve this?
Store sessions in the database
Add a field called, say, "inuse" to the session document
Set that field to 1 when storing the session
Add a unique index with that key
This will prevent your application from being able to store more than one session at a time.
You would then need to devise a mechanism for expiring sessions that are abandoned (i.e. user doesn't explicitly click "log out" button) as well as figure out what to do if, say, your browser crashes and you can't use the established session but it's still within the session inactivity timeout.
How can I create sessions and manage them in Node.js without a framework like express?
I know it would be much easier to use express but I want to know how to do it with node just in case.
Most of the questions that mentions managing sessions in node is using express to do so but I want to know how to do that without express.
As a simple starting point, suppose we starts sessions when a user login and destroy when he logout.
So when a user login, we basically create a unique session-id and store this session-id at some db like redis/mysql at our server, same will be given to client for next subsequent requests. (Note do not store session-id in memory of the server, as if the server restart we will loss this sessions)
So next time whenever a new request come from the client with session-id we will identify the user and serve response on the basis of that session-id.
Whenever user logout, we remove the session-id from our db. Similarly we can add timeout for the session-id.
This is a simple concept, it can be extended as required.
I wrote a simple webserver with nodejs and express. I implemented an user authentication with email username and password. Furthermore I have a remember-function which stores the user id and pwd hash into a cookie. Now I would like an extra session that ends when the user will close his browser or click to the logout button.
Which way is the best practice for implementation? Is the session the same like the remember-function with an expire time and in each request I must check the credentials against the database? (I'm not that sure about this)
Technologies that I'm using: nodejs, express, mongodb
This is not a nodejs question only, I would prefer a general explanation for the problem.
Let me get this out of the way first; Storing the password hash into a cookie would allow anyone to login when they have the password hash and that would be disastrous if the password hashes ever got exposed for some reason. Encrypting cookies is just fine, but don't allow the actual hash you store in the database to be used for authentication. Ever.
About re-authentication, Node is a technology that operates on a single thread and is scaled by running more instances over multiple processors and/or machines. Keeping sessions is a good idea to avoid trips to the database, but you have to think about the architecture as well. What happens if you, say, use sessions stored in files (ala PHP) and you need to scale to multiple machines? Nothing good, at least. So you need a central point to keep track of the sessions.
This can be either your database (MongoDB) or something such as Redis, or another centralized mechanism allowing you to check sessions. Either way, you will have to spend time doing the request and retrieving the session values for the client. If you do not have additional values you need to store it makes no sense to create a dedicated session architecture (that needs expiration, and so forth) and just doing the authentication again is the easiest and most logical solution.
Personally I almost never need sessions and just do authentication again.
I want to restrict number of sessions that are logged in as admins (to 1).
I would like to just go through the list of active sessions and check if they are logged in as admin. This way I don't have to track login, logout, sessions expiring. Unfortunately there seems no obvious way to do that.
I know there are concurrency issues, but creating a simple lock around the code is simple enough.
Using cherrypy 3.2.I'm using in-memory session store.
Found a way using some of CherryPy internal structres:
for id, session in cherrypy.session.cache.items():
if session[0].get("login") == "admin":
admin_count += 1
Where "login" is any session parameter.