Hi, Lucas!
I'm not telling about best practices, but from my experience:
Yes, you can use JWT + Passport.js for the purpose you described. Passport gives you the simplicity of integrating many authentication schemes such as raw email + password, Twitter, Google, etc.
You can also use just JSON web tokens, it will be simpler as you don't necessarily need Passport.js. Say, you have "/sign-up" endpoint where you create a JWT token and write required payload (in your case it is at least a role of a user) and send it back to a client and "/sign-in" where you authenticate a user. When a client makes a request to your backend, you can parse[1] a JWT token to extract a user's role and define the next logic.
[1] For this purpose you can have a middleware, which can be used in protected endpoints, that extract a JWT token from a request (e.g. a client sends a token in the request body), decodes it and receives a user's role (and other payloads if you put it there) and you can put the extracted payload to, say, "req.user", so it will be available in your next functions (endpoints handlers - controllers):
"The relationship between a STORE user and it's sub-users would be one-to-few. So, should I have them referenced inside my schema or actually embed them inside the STORE schema?"
You could embed other documents (users as you say) to a user document, like this:
// define a User model, pseudocodeconstuser=mongodb.Schema({email:{type:String,required:true,unique:true},role:{type:String,required:true},password:{type:String},// you'll put sub-users hereusers:{type:Object},})
But this method has cons:
"users" field uses a document space not in a good way: takes additional space + duplicating users.
what if you need to know if a particular user is belonging to a store? You will need to fetch all the stores and parse their users to find out.
in case of updating "user" schema - e.g. adding/removing/changing existed fields, say, you rename "email" field to "emailAddress" and add a field "name" with default value - in this case, "users" you put in stores will be outdated and you need to make additional checks on documents fetching or to make a manual migration.
So, it is better to make a reference, like this:
// define a User model, pseudocodeconstuser=mongodb.Schema({// ... user's fields// so, "users" is an array of User referencesusers:[{type:mongodb.ObjectId,ref:'User'}],})
And in case you need to find out what users belong to a store, your query will be:
// mongoose pseudocodeconstusers=awaitUser.findOne({email:storeEmail}).populate('users');// "populate" will fetch users documents by references
Wow Sergiy, thank you for your detailed response. I am glad that I actually fully understand both.😁. I didn't think about the cons in embedding before posting. It makes sense to me the pros in referencing. Thanks again!
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Hi, Lucas!
I'm not telling about best practices, but from my experience:
[1] For this purpose you can have a middleware, which can be used in protected endpoints, that extract a JWT token from a request (e.g. a client sends a token in the request body), decodes it and receives a user's role (and other payloads if you put it there) and you can put the extracted payload to, say, "req.user", so it will be available in your next functions (endpoints handlers - controllers):
You could embed other documents (users as you say) to a user document, like this:
But this method has cons:
So, it is better to make a reference, like this:
And in case you need to find out what users belong to a store, your query will be:
Wow Sergiy, thank you for your detailed response. I am glad that I actually fully understand both.😁. I didn't think about the cons in embedding before posting. It makes sense to me the pros in referencing. Thanks again!