Current session id in sails js - node.js

I want to delete all sessions from all devices by one click in sails.js. How to get the current session id?
For example:
console.log(req.session.sessid) // sess:jV-M6_ZNCp-8x_jYPbSfbUilXd_T85i_
sails.js version 1.1.0-3

All sessions are unaware of which user they belong to unless you've mapped the session in a persistent storage system like Redis/Memcached cache or MySQL, MongoDB database.
One of the many solutions I could think of is as below:
Create a model in your sails app which can be called SessionMapper
Add three columns: userID, sessionID, and isActive (boolean).
Now whenever a user signs in, create an entry in this model/table.
Create a middleware through which all API requests (except /login and public APIs) will flow
This middleware will check if the current session is still active -- acting like an extra layer of authentication.
If the session is active, grant access / next()
if the session is invalid or isActive === false, log out the user internally and redirect to login page with some message.
To sign-out an users all active sessions, set isActive = false for userID = <user-id> in SessionMapper model.
Note: This method will increase a lot of READ operations on the datasource which is connected to SessionMapper. Move it to a better and efficient solution like Redis/Memcached if it hurts the primary operations.
I hope this pseudo code help you achieve your task. #tspentzas, the next time when you seek for a solution-- kindly add whatever you've tried so far in your question for the community to help you in a better way.

If I understand correctly from your question, req.session.destroy() is your answer.
https://sailsjs.com/documentation/reference/blueprint-api/destroy

Related

How to make a single user authentication and authorization? Or how to restrict number of users registering to an application in node js?

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.

Should I use cookies, sessions, or user accounts?

I'm trying to develop a website for reviewing TV series, and I want to limit the rating for a show to one rating per user, and I kind of have no idea where to start, since I'm very new to web development. I'm using Vue.js on the front-end; Node.js with Express on the back-end.
From what I understand, cookies should not be suitable for this purpose since they can be deleted by the user, am I right?
I've also read about sessions and how they are stored on the server rather than the browser (but I also don't know what sessions are or how to implement them).
There's also the user registration system possibility. So, which one of these methods should I use for this purpose?
If you could also tell me about where to start (direct me to tutorials, code snippets, ..) I would be really grateful. Thanks.
Like said by Mr. Anonymous, you need User Accounts. However you could achieve this using in your case, for example, expressjs/session to create sessions and passport.js for the user authentication part.
Here there is a simple tutorial using these two libraries and mongo-db for saving user data.
If you want implement your own session library (only for learning purpose), you can follow these advices.
You need to use all 3 and if your new to web development this will take you some time to get right. You will need user registration, a login system, and when users log in you will create sessions ( which internally use cookies) and if you want them to login with "remember me" you need to explicitly use cookies.
Sessions
This is how express/your-web-app will remember that a user is logged in. Under the hood its using cookies on the users machine that map to ids stored in memory on your server. Without sessions and cookies your users will have to log in on every page....You don't have to worry about how sessions use cookies yourself. There is express middleware libraries that handle this for you so you just interact with sessions like any other object, but its good to know that sessions internally use cookies. You can find lots of articles expanding on this.
Cookies
You will explicitly have to create cookies if you want to give your users the "Remember Me" login option. If you don't care about that then you can force them to log in and then create a session so they wont have to log in again for 20 mins or however long you want.
User Accounts
User accounts are records in a database that uniquely identify each user. The sessions and cookies all point back to this. That is where your store your users information such as their username, email, and whether or not they have already voted on a TV series. When a user logs in you lookup their identity in your database and if you find one you then create a session so they don't have log in again as they navigate your site for a set amount of time.
Recommendation
Start small. Forget about Vue.js for now and use plain HTML until you understand these basic components sessions, cookies, and how to build a login and registration page. If, and I respectfully mean if, you get that working then you can work on making it look pretty and fancy in the front using Vue.js.

PassportJS - Is it possible to change req.user for another user?

In my application, I have implemented the ability to change a users permissions, rank, etc. It works great, if I update my own permissions, I can see the changes instantly since I can update the req.user object via req.login(). Problem is, when I update another users permissions, it updates in the database just fine, but the user will have to relog to see their permissions change since req.user still thinks they don't have the permission. This is fine if they're not logged in of course but if they are, I'd like the change to be reflected immediately for them if possible.
So I'm wondering if there's a way to update another users req.user object so they can see their permissions change right away without having to log out and back in?
Or possibly a way to logout and login that user before returning?
Since the permissions are in your own database then sure you can, but how to do it depends on your app.
Given you are using sessions, object stored in req.user is loaded separately for every HTTP request by using the function you provided with passport.deserializeUser. Often you would store the user ID to the session in passport.serializeUser, and then retrieve the user from the database with the ID in deserializeUser. Thus, whenever a request is being handled in the backend you would generally have the latest information in req.user, including the permissions. Naturally your frontend also needs to somehow get the new permissions and adjust itself (eg. if you add admin rights to user, you probably would want them to see the admin options in the UI).
You could of course just pass the whole user object to the session store and skip one database call per request, ie. using these:
passport.serializeUser(function(user, cb) { cb(null, user); });
passport.deserializeUser(function(user, cb) { cb(null, user); });
for session handling. If you do this then the database changes are not reflected upon the req.user object. If the user updated their own information you could just call req.logIn(...), but that you cannot call for other users. You can work around this though - eg. notify the user in question over websocket and make their browser call a route that calls req.logIn with the latest user object, or dig into the session store and manipulate the data there directly.
Or, since forcing a logout is an option you could follow enRaisers answer and locate the users sessions from session store and delete them all which is effectively logging out the user from the backend. You can go through the sessions via the API, or if you use a database (eg. connect-mongo or connect-redis) for session store you can also open another connection to the same database and use normal search and destroy methods. Again you still need handle the logout in the frontend by yourself somehow.
You can try to delete the session , or regenerated the sessionID. but this will force that user to re-login.
In case your sessions are stored in mongodb. then you can check collection by name app_sessions and it has a field by name userId.
in Express session there is a module called store. and it providea many API to find session by sessionID. but unfortunately no API to find session by userID.
So if you want to use the session store API then you can call store.all , which will give all session. But this is really cruel method. becasue I dont know how much data it may be holding.

ExpressJS/PassportJS: Authentication vs. Sessions

I am starting out with NodeJS (and web programming) and having trouble getting the authentication and sessions understood. I read many tutorials and just when I think I had it, I get confused. My problem is dealing with both authentication (Signup/Login) and persistent sessions.
I am using PassportJS, and after many tutorials later, I think I finally found a great one here: https://scotch.io/tutorials/easy-node-authentication-setup-and-local
But now I'm confused how sessions are handled by serializeUser and deserializeUser. Please bear with me for this novice question, but my understanding is a that a user ID is used to track the sessions.
So my questions are:
The user ID, is autogenerated by Passport?
Serialization simply adds the user ID to the session cookie?
Finally, how can I change the session parameters like maxAge? Where should I set them? I'm a little confused with Express sessions and the Passport sessions.
If anybody can provide a link to a good tutorial that is appreciated too.
Thank you.
Passport does not directly manage your session, it simply uses your session. So you will configure the life of your session based on the middleware you use. With express's own cookie middleware, for example:
app.use(express.session({ cookie: { maxAge: 60000 }}));
As far as Passport, it does not generate anything. It invokes your authentication, serialize, and deserialize functions to find, load, and reload the user data. The flow is like this:
passport.use(<new Strategy>(function(username,password,done) { }))
This accepts a login form submission with a username and password value that gets passed into your implementation. Typically a DB lookup that produces a user object (based on your model/implementation) passed into the done(err,user) function.
Now that you've found a User object it will be set onto the request object, but that is only good for that request. The session is used to serialize the user (typically the ID of the user object) so that it can be passed in again to reconstitute a user.
my.serializeUser = function(user,done)
This is your function to which Passport passes the User object you found. This is where you construct a String representation of that User and pass it to done(err,string) Whatever you pass as the second argument gets stored with the session.
my.deserializeUser = function(string,request,done)
This is your function where the key (created by your serializeUser) gets passed back to you. Your code then uses it to retrieve the full User object (possibly a DB query by that user's ID) and pass back a full user object to done(err,user) This again gets set on the request for your handlers.
So it's all up to you how to serialize, deserialize, and authenticate. Passport provides the hooks so that you can set auth requirements on routes the same way despite the strategy you pick.
I can give you a few link to understand it better. The key is to write better code, you have to see the better code.
This link from AirPair CEO brings much-needed clarity, especially the last part as we all use Express 4 now.
Second would be this one toon.io. This one really opened me up a lot. I am still unclear on many things, will add to it Once I get more clarity.
One thing which people fail to mention in their tutorial is that in the production environment you cannot use Express's traditional data store. Obviously express also needs to maintain a table and it uses something called Memory Store. To use your own session store see here.
Hope it helps someone.

Node js - user auth, what to store in session?

First of all, I did not find any similar questions or material that will be useful. I'm sorry if I missed something!
Second of all, I'm not interested in ready solutions like node-passport or connect-auth or everyauth
Now to the question. I'm using Redis to store the express session. My question is, when user is authenticating (i.e. after a post of username & password was made and such user was found in the collection) what should I store in the session?
I can store the whole user object (for example, the way it came from MongoDB). One disadvantage that I see, is that when user is being modified in the DB (he edited his profile), Ill have to "re-set" the user object in session. It gets even more complex if for example the user's profile is changed by administrator - in that case the session have no idea that the user was modified and its data needs to be refreshed from the DB hence the sessions is currently holding outdated user object that will be updated only the next time the user logs in.
Create a collection of "hash => userid" and store in session only the hash. Then every request, call a middleware that will check (pseudo code below, omitted the check for non existing hash, in that case user might be considered as not logged in since the session expired):
if(userhash in req.session) res.local.user = db.users.findById(db.sessions.findUserIdByHash(req.session.userhash));
Well the obvious disadvantage of this method, is the additional collection (i.e. mongodb) or key => value (i.e. redis) storage for hash => userid which also requires some procedure to clean old session hashes (scheduled task\cron that will run and delete old expired hashes).
Another solution similar to #2, instead of using 3-d party collection/key=>value storage, store the hash as part User object in MongoDB. This method however eliminates the extra collection/redis key value, but still required a scheduled task to clean old, expired sessions. And since expired session will probably be defined by "expire date" attribute, its easier to maintain 3-d party collection for active session, instead of putting session related data into User object in MongoDB (thus making the User object huge).
I'm new to Node-js this why I ask. I also understand that there might be no correct answer, and or it might be bounded to personal preferences.
Thank you!
There's really nothing special about a session in Node/Express as compared to traditional frameworks (like PHP/ASP/whatever). What would you do with a user login in PHP?
Just store the user ID in session. Pull the user data from Mongo when needed.
Session data is secure (in that a client can't fiddle with it like they could with a cookie), so you can rely on a session's user ID pointing to user data that has been properly authenticated.

Resources