PassportJS authentication and mongodb database collection best practices? - node.js

I am working in a project and actually the first time using nodejs, express and mongodb. For the authentication i am using passport.js which look pretty flexible and easy to integrate it.
I really like the idea of Serializing and Deserializing but my concern is about the user object which is always ON and can be used on every request.
My project involve subscriptions, user profile and maybe a small ticked system.
So my user schema it contains user credentials, user info like address, phone, email and also information about the subscription. Some of this information is embedded documents with in same schema. It seems weird that all this info is always ready even i do not needed, even the bcrypt password is always on the request call.
My question is, do you think is best practice to separate the user credentials from the user object and play with relationships soi can call the user info when i need it with normal controller model way?
Thanks in advance

if you are referring to sessions you should really only be sending a small piece of data with the request such as a user id. The entire user document should not be going across with every request.

It's common practice to separate user credentials from the rest of the user data, because the credentials need to be stored in a very secure manner - so much so that it dictates different infrastructure.
I work at Stormpath and we provide this as a service. We store the password for you, with very high levels of encryption. We have a great integration for Express, you check it out here:
https://github.com/stormpath/stormpath-express

Related

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.

Check user permissions in RESTful API

I'm developing a SaaS API with NodeJS, Express, MongoDB. It has implemented a JWT authentication/security methodology.
In my personal case, I have (for now) two collections: User and Client.
You can see the fields that each collection has (for defining purposes). So in terms of endpoint design I'm using a trully restful approach so:
/api/users/{userId}/clients: to insert clients i.e.
This is exactly the point I'm bringing I want, that before posting a new client to check if the price plan allows the user to do that. In terms of logic:
function post(req,res){
// Check if the JWT user.id is the same of the endpoint request
if(req.user._id == req.params.id){
// Here I want to know which is the price plan and to count the Clients that the user has
}
}
In terms of my doubts I have thought in some hypothesis but I truly don't know which one is the best:
Do a query in the User collection get the price plan, do a query count on the Clients collection validate and then post the new Client.
Put the User's price plan information in the JWT, do a query count on the user's Clients collection validate and then post the new Client.
These are the two main possible solutions I thought about, but I have serious doubts security and performance wise of which one I should implement/follow.
Thank you in advance.
I have same doubts. Also if you put anything into your tokens, then when information change, you will have to reissue those tokens (will have to make user login and logout) or implement complex token update logic. Also application evolves: today you need price, tomorrow something else. Changing every time tokens of all users (using it as distributer storage by fact) is not a good idea probably. That's why it is better to keep JWT as short as possible.
Your question is more opinion based, but as my own opinion, I would definitely store in jwt only userId (+ meta information if needed). But not app specific things. Reading from database is the way to go.

Authorisation strategy for a first-party express based node API

I'm tackling the design of my first API and am struggling somewhat with authorisation concepts - I was hoping some kind people could give me some advice!
What I'm building:
An API that will eventually be accessed by third party apps and a mobile app.
A web-based 'client' (first-party single page app) that will use the API. (Should this first-party app be 'a part' of the API, or a completely separate node app?)
Technology I plan to use:
Node
Express
Passport
Mongodb with Mongoose
I'm not wed to express or passport, they just seem like the best options and are well documented - bit I wouldn't want a potential solution to be dismissed because of alternative dependencies. Same with Mongoose, I actually prefer the look of Monk (or even just Mongojs), but every tut seems to use mongoose, so seems like the safest option for a node beginner.
Authenticating a user is simple enough (I've gone through the fantastic Beer Locker tutorial), what I'm struggling with is ongoing authorisation. Naturally I don't want the user to have to input a username and password with every request they make - should this information be stored locally and sent with every request? (if so, how? I can't find any info on handling an API with a session) or should I be working with tokens of some sort? The small amount of reading I did on 'Digest' authorisation (including the Beer Locker tutorial follow-up) made it seem like it had security issues, at least with the Passport implementation (this I don't fully understand, but seems to relate to hashing passwords, which passport doesn't do as standard, and only MD5 is supported even if it's added?).
I have built a working API that I can authorise with 'Basic' (directly, through Postman), so I have the foundations in place - authorisation works, I just need the tools to take that to the next step and add sessions into the mix!
I've been trying to get my head around this for a couple of days now, but I fear I'm too stuck in a more traditional local web-app workflow - the whole API thing is throwing me somewhat.
Any help is hugely appreciated, even if it's just pointing me at an appropriate tutorial - the above set of requirements must be quite common!
I have come accross this problem too...
I can only recommend doing this for the beginning:
http://scotch.io/tutorials/javascript/easy-node-authentication-setup-and-local
tell me if it helped :)
As I understand you have done the authentication and the only thing you have to do now is store somewhere that the current user is authenticated, his name, roles etc to use later with other requests. In the Passport you will do it in the function callback (instead of the "If this function gets called..." comment).
Now you have to decide, you have two options:
Store the user information (name, roles etc.) on your server (in a session) and give the user some long code which will identify his session for the next requests
to store the information on your server you may use for example the express-session middleware
it would be probably best to save the session identifier in a cookie, but read some security issues before
Give the user something that would prove to you he/she is authenticated and which name, roles etc. he/she has
you can generate a token, that contains the user information (name, roles etc.) that the user will send with every request. to know this token is legit, you will have to sign it. more on this is on jwt.io and you can use express-jwt middleware.
you dont have to care about storage of session with this one
the token can be placed to a cookie too, but same security issues apply. it is still considered better that localstorage (more here)

How to ease CouchDB read/write restrictions on _users database

In my couchapp two databases are being used
1 Is for application data
2 Is "_users" database.
In my application In one form I'm trying to implement autocomplete where data source is a "view" created in "_users" database.
Now when I login with normal user id other than admin. While trying to access the view inside "_users" database I'm getting the error 403 which is :
{"error":"forbidden","reason":"Only admins can access design document actions for system databases."}
Is it possible for me to allow and limit the access for non admin users to that view only ? So I can get the list of users from _users database into my application.
I've never been able to do many tasks that require much custom with CouchDB by itself. I've always needed a script somewhere else that gives me the info that I need.
What works for me is this setup:
A gatekeeper Sinatra app that has admin access to my CouchDB
Using CouchDB's config to proxy to my Sinatra app. httpd_global_handlers _my_service {couch_httpd_proxy, handle_proxy_req, <<"http://127.0.0.1:9999">>}
The reason for the proxy is because any request that comes through to your gatekeeper will have the AuthSession token set. Inside your gatekeeper, you can GET localhost:5984/_session passing the AuthSession cookie along, it will tell you who is making the request, allowing you to look them up and see if they have access, or just give everyone access to whatever you like. Another reason for the proxy is to avoid any CORS nonsense since you're making the request to yourserver:5984/_my_service.
Update
A purely client-side/javascript solution means that it will be fundamentally insecure at some point, since well, everything is on the client-side. But perhaps your application, doesn't need to be that secure. That's up to you.
One workaround could be to make your application authenticate as a predefined admin, and then create more admin users that way. You could authenticate once when your application boots or on an as needed basis.
The "problem" is that CouchDB sees the _users database as fundamentally special, and doesn't give you the opportunity to change the credential requirements like other databases. Normally you would be able to use the _security document to give role based or user based access. But that's not possible with _users.
An alternative implementation might be to keep track of your own users and forgo the _users database altogether. In that case you could set your own cookies and have your own login and logout methods that don't depend on CouchDB's authentication scheme. You could query your own _view/users because it would be in your main database. Things wouldn't be locked down tight but they would work fine as long as no one was interested in hacking your system. :)

General user session handling (Nodejs)

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.

Resources