i am just a beginning, with node/express and i kinda have a problem.
i have built a todo application using, node js express and mongo db which actually has an login/register form...i.e, u get to register and login (/register) and(/login) before you can get access to the todo application(/todoapp).
My problem is, if user A logs in with his email and password, inputs some todos and logout, later on user B also get to login with his own different email and password, he gets to see the todos of user A.
but then i want it to be different, user A should be able to see just his own todo, user B should also be able to see just his own todos, please how do i do that?
Please my algorithm is below
-user registers (/register)
-user gets redirected to (/login)
***successfully logins and gets to (/todos)
this works perfectly and sends all logged in users to the same (/todo)
Generally you need to store the user _id in a session or a cookie (in the client side) when the user login successfully, then when the user make get/post request first you check if the _id in his seesion/cookie match to the _id in the db and sending back to the user only the items with his _id (items that belong to the user).
you can register a session when the user logs in but keep in mind you must to protect against csrf.
You can also use JWT for this.
I will suggest you to find good tutorial for JWT or authorisation with session and csrf protect.
Its a big subject and its better to watch a good video or read a good article than copy paste code from here.
Related
I have an app that recommends gifts to the user, after they answer a couple of questions. In the case that the user likes or dislikes a gift, I need to send an update request to the db to update it's 'liked' field. Users are not required to sign in order to like/dislike questions. The app is built using Angular and used Express at the backend to do the CRUD operations.
My question was, is there any way this operation can be done in a secure way, so that the user can not open the dev tools and get the info which would enable them to send repeated requests or anything like that? Is there anything I can change in the Express code? Or would I need to change the security rules?
Express should have a way to identify duplicate request. User id or some kind of token should be with request. But I see that sign-in of user not required in this case.
You can generate a temporary token every time some gifts are shown to user. This token should be generated and saved temporarily on express and you can send it with gifts data. So now when your frontend send request for like/dislike, this token will be in request.
So now express will do following steps
Checking if temp token is valid (it can match it with saved tokens)
If valid then it will update the database (like/dislike)
After successfully update it will remove that temp token.
So now, even if user send duplicate request it will be rejected by express as temp token will be not valid.
I hope it will solve your problem.
I was building my chat app and i prepared the login page to authenticate the user logging into the application not the question if what should i do with it, I used POST method to get the credentials and compared it with the database, now how should i send this to the front end page so as to make user logg in and send message by the username they have logged in.
i do not want a piece of code but rather I'd like to have a suggestion on what should i do next and what should i do next, if i just send the plain username into the frontend then i am afraid that users can change its value and pretend that they are someone else.
You don't send it to the frontend page. You never send password or any other sensitive information to the clientside/frontend/browser
The flow is roughly like this.
Frontend has a login form that posts to the server
Server gets the username and password
Server authenticates and creates a session
Frontend gets information that this user is now logged in.
Every action this user takes has to be check on the server side.
You can also check my answer on similar thougt:
VueJS Secure with Auth0 - How is it secure?
Where the author asks:
If I set some variable like isLoggedIn = true or isAdminUser = true,
what stops the user from manipulating the DOM and forcing these values
to true?
The short answer is nothing. You don't do any authentication on the client side. Its ok to have some variables like isLoggedIn or isAdminUser to make the interface make sense but the server code should always to the actual authentication or authorization.
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.
So I've created a socket.io chat app and I'm needing to store the following details on the browser (so I can easily access them when they revisit the site):
User auth token ( A user is validated with this token, it's unique to the user)
Chat Id ( This is there so when the user wants to send a message I can simply append the chat Id to the function ) - So basically the user will send a message to this chatId
What I've done so far is use html 5's localstorage. From what I've heard it's not secure at all and a lot of browsers do not support this!
Any ideas? I was thinking maybe I just store the userAuthToken in a cookie and whenever they visit the site, it simply queries the server which returns the chatId's that the user is apart of. Or maybe some sort of node session store? I'm using express, node, and socket.io
So I've gotten Passport to work with Node.js and MongoDB for session management which of course conveniently provides access to the user object in the request header. However, at least for me, Passport sets this object to be the entire account document from MongoDB. For the schema I've created, this includes everything about the user - email, name, hashed and salted password etc. So I have two questions about this.
First of all, is it really secure to send all that info back and forth between server and client over and over again? Sure it's sent over SSL and the password is hashed and salted - but all the user info is still in there. Should my schema demand user info (personal info not needed for authentication) be kept in a different MongoDB document? Even if I did that, the hashed password would still be passed back and forth. Is it assumed that SSL prevents that data from being eavesdropped? It just seems that if someone hypothetically managed to suck up every header sent to my app, they could just recreate the user database and perform a rainbow table attack.
Second of all, on the server side, I've (naively?) been using the request header username element (req.user.username) to determine which user is connected and authenticated. But, it seems that if a user just changed their header to be a different username, my code would allow them to masquerade as a different user. So should I be verifying the identity of the request by another means, instead of just using the plaintext username available? Or am I completely off the mark as to how these headers are stored, generated, and passed, and this isn't actually a security issue? If so - can someone elaborate a bit on how these headers from Passport are actually created?
For your first question, no, it is not ok to send everything (including password hash) to the user, that would beat its purpose and as you said and very well, once you someone had the hash, would be much easier to do a brute force attack (you don't that data to be exfiltrated from your app)
As for the second question, you should have some middleware or plugin that validates that the cookie present on the request is actually valid and generated by you in the first place, it is ok to use req.user.username for Authorization purposes in route handles once you validated that the user has previously Authenticated in your system (through the cookie)
Be sure to check out this blog post on how to build secure express apps https://blog.liftsecurity.io/2012/12/07/writing-secure-express-js-apps but in case you are still considering which framework to use, I would take a look at Hapijs and its bell plugin for authentication and https://github.com/hapijs/hapi-auth-cookie to keep session.
Good luck! :)