Excellent tutorial. However, if I am to be nitpicking, you may want to change "ok" to "success". It does the exact same thing, but the industry as a whole has decided that "success" is the word to use to verify a request. Personally, I don't think it matters, but if you use standard nomenclature when writing demos for job applications, you are far more likely to get the job. The mindset behind the code is still 100% correct though. We don't just send a different key, like "not_ok" or "unsuccessful", but rather flip "success"/"ok" to false if it failed. This is because some failures won't send any response at all, so even if there is a communications error, you can still just look for if that "success" is true on the receiving end. It either being false or not existing at all will both then produce the error message. If you want to go a bit more advanced, you can also add an error array with the error code, a user-friendly message to display front-end and a dev-friendly message to display in the log. Though don't have your code rely on this error array existing, as a communications error will not produce it.
its really rare to find tutorials like this one simple with great explanation and straight to the point with out using tons of unnecessary libraries and tools that will make the video much longer and complicated for no reason thanks
The error im getting while starting the server is using the middleware for the routes/messages.js as when i do router.get('/', [auth, admin(or any roles)], (req,res) => { ... } im getting error i guess. as middleware is using object instead of function. is there anything that can be done?
You would need the password and the email to get the token, and the token is valid for 15 minutes. So yes, if you did this in the front-end you would leak your token. And if you're wondering if you could just put in a random token, you can't since it has to be generated by this implementation try to Google: JSON Web Tokens, to see how it works.
In demo you have shown the post call from post man, I see header specified, you never showed the header. I am not sure if it matters, but i am getting 400 error on the first post to get token.
Great video! Simple and to the point with all the relevant information. The client side would be very interesting to see with one of the common frameworks out there.
You shouldnt send the token to the server through header, cause that means client side the token will need to be stored somewhere. You need to use secured httponly cookie for that. Only the webbrowser can access it, and not the javascript, preventing agains xss attacks. That's an OWASP recommendation.
can you make videos about part 2 plz!!!!!! i really need user vaildation and database tuts for my project, It's hard to find out the most secure way to do all these things, and your tutorials are super good!!!!! I have your channel on notification, I'll watch as soon as it comes out!!!!
If you want to look into user validation and databases, then I would point you towards studying MongoDB and specifically, MongoDB Atlas. Atlas is a fantastic service that allows you to spool up a database through AWS hosting or Google hosting, among others. It is excellent for security as it operates on a whitelist only principle- that is, you must whitelist your IP and any other IP that tries to request the data is going to be rejected even if they provide credentials. Start there, and write a test program in express that has basic CRUD functionality. Create, read, update, delete... for a User model that represents each user. Pro tip- if your referencing user data in other documents, set your reference to the unique ID of the user instead of the users email. Users often need to change their email and if this happens your data references will break. Dont ask me how I know, lol. But yeah, TLDR MongoDB Atlas for DB and express backend is uber secure if you use modern techniques like JWT and Bcrypt, combined with whitelist only and separately hosted databases. To take things a step further, enable TLS/SSL to secure data in transit. And further yet, encrypt ( different then hashing, do research ) the password so its not sent through the internet in plaintext in order to dodge packet sniffers and stuff. Then decrypt and compareHash on the server side only. Not invincible but hackers need to take extra time to find the decryption keys buried deep within your frontend bundle if they are to decrypt a password they have potentially sniffed.
I tried this, and when I send in the email and pw (I redid the token every time) Node server ends and points to " if (!user) throw new Error("Invalid email or password."); " in routes/auth.js. all packages are installed and up to date. I pretty much followed through this entire video and checked with your git codes, so I;m not sure where I went wrong, or can it be Express that's causing problems?
Have you tried to regenerate the password? I believe I remember having a similar issue and the problem was when the bcrypt password was generated on a different machine, it wouldn't work even though the password was correct. And if that doesn't work try to add: console.log(req.body); console.log(user); To /routes/auth.js (roughly on line 17), and show me the output.
and how can I encrypt that data sent and received from the server? Anyone can enter my app with a fake name and password just by changing the server response from ok:false to ok:true. This can be easily done using burpsuite
video is great ..but yeah you could have explained more on the auth rote and auth.js , keep creating awesome videos and subscribers will turn up......in large numbers....
The short answer is yes. So I would recommend having some logic on the client-side that would refresh the token, so the user wouldn't have to sign in every 15 minutes.
That's a good question, the simplest thing to do is to shorten the time from 15 minutes to 5 minutes, that still doesn't solve the problem. But if you really want to fix it you could always do some extra checks on the server side, to make sure that the person actually has access. That could be done by including an ID in the JSON web token and then checking if the user still has access or not. So even if the token is still valid the check would still ensure that deactivated users wouldn't be able to access the platform.
Wherever you are storing the state that the user is disabled that's where you want to check. So if you're not using a database you don't have to be using a database, hope it makes sense. Here's some pseudocode: /routes/auth.js ... // Dummy data const users = [{ enabled: false, email: "vincent@vincentlab.net", password: "$2b$15$zqY2Q4eOoGzFpZkHJz9HS.BSfXc/HM2E/yTWa1awFmTMgN2bE72Uu", roles: ["admin", "editor", "viewer"] }]; // Get to user from the database, if the user is not there return error let user = users.find(u => u.email === req.body.email); if (!user) throw new Error("Invalid email or password."); // Maybe you could return a nice error message here if(!user.enabled) throw new Error("User is deactivated."); // Compare the password with the password in the database const valid = await bcrypt.compare(req.body.password, user.password) if (!valid) throw new Error("Invalid email or password."); ...
Excellent tutorial. However, if I am to be nitpicking, you may want to change "ok" to "success".
It does the exact same thing, but the industry as a whole has decided that "success" is the word to use to verify a request.
Personally, I don't think it matters, but if you use standard nomenclature when writing demos for job applications, you are far more likely to get the job.
The mindset behind the code is still 100% correct though. We don't just send a different key, like "not_ok" or "unsuccessful", but rather flip "success"/"ok" to false if it failed.
This is because some failures won't send any response at all, so even if there is a communications error, you can still just look for if that "success" is true on the receiving end. It either being false or not existing at all will both then produce the error message.
If you want to go a bit more advanced, you can also add an error array with the error code, a user-friendly message to display front-end and a dev-friendly message to display in the log. Though don't have your code rely on this error array existing, as a communications error will not produce it.
I did not know that, but I completely agree thanks
its really rare to find tutorials like this one simple with great explanation and straight to the point with out using tons of unnecessary libraries and tools that will make the video much longer and complicated for no reason thanks
keep on filming, those tutorial are great! Your channel will blow off eventually
Thanks, will do!
hey Vincent! it's been awhile but this look really interesting! looking forward to the premier of it!
Good work man, you have a talent, keep making videos, if you upload consistently great things will happen
great video! Just that I checked the video again and the question is solved xD
The error im getting while starting the server is using the middleware for the routes/messages.js as when i do router.get('/', [auth, admin(or any roles)], (req,res) => { ... } im getting error i guess. as middleware is using object instead of function. is there anything that can be done?
Hello vincent, ive got a question to ask, whats stopping the guys just taking the token and then use postman to change data with?
You would need the password and the email to get the token, and the token is valid for 15 minutes.
So yes, if you did this in the front-end you would leak your token. And if you're wondering if you could just put in a random token, you can't since it has to be generated by this implementation try to Google: JSON Web Tokens, to see how it works.
Very practical and quick. Thanks.
In demo you have shown the post call from post man, I see header specified, you never showed the header. I am not sure if it matters, but i am getting 400 error on the first post to get token.
what is middleware in this app's
context
Looking forward to your next new video 😃
That was so practical, thanks.
Great video! Simple and to the point with all the relevant information.
The client side would be very interesting to see with one of the common frameworks out there.
Great suggestion!
I agree, quick and easy to follow, the nitty-gritty details can then just be implemented by the developer using this, like environment variables, etc.
Thanks for the video! How can one handle token? With google sing in? Do we store the token from the Google directly?
what about key-based apis?
You shouldnt send the token to the server through header, cause that means client side the token will need to be stored somewhere.
You need to use secured httponly cookie for that. Only the webbrowser can access it, and not the javascript, preventing agains xss attacks.
That's an OWASP recommendation.
can you make videos about part 2 plz!!!!!! i really need user vaildation and database tuts for my project, It's hard to find out the most secure way to do all these things, and your tutorials are super good!!!!! I have your channel on notification, I'll watch as soon as it comes out!!!!
If you want to look into user validation and databases, then I would point you towards studying MongoDB and specifically, MongoDB Atlas. Atlas is a fantastic service that allows you to spool up a database through AWS hosting or Google hosting, among others. It is excellent for security as it operates on a whitelist only principle- that is, you must whitelist your IP and any other IP that tries to request the data is going to be rejected even if they provide credentials. Start there, and write a test program in express that has basic CRUD functionality. Create, read, update, delete... for a User model that represents each user. Pro tip- if your referencing user data in other documents, set your reference to the unique ID of the user instead of the users email. Users often need to change their email and if this happens your data references will break. Dont ask me how I know, lol. But yeah, TLDR MongoDB Atlas for DB and express backend is uber secure if you use modern techniques like JWT and Bcrypt, combined with whitelist only and separately hosted databases. To take things a step further, enable TLS/SSL to secure data in transit. And further yet, encrypt ( different then hashing, do research ) the password so its not sent through the internet in plaintext in order to dodge packet sniffers and stuff. Then decrypt and compareHash on the server side only. Not invincible but hackers need to take extra time to find the decryption keys buried deep within your frontend bundle if they are to decrypt a password they have potentially sniffed.
I tried this, and when I send in the email and pw (I redid the token every time) Node server ends and points to
" if (!user) throw new Error("Invalid email or password."); " in routes/auth.js. all packages are installed and up to date. I pretty much followed through this entire video and checked with your git codes, so I;m not sure where I went wrong, or can it be Express that's causing problems?
Have you tried to regenerate the password?
I believe I remember having a similar issue and the problem was when the bcrypt password was generated on a different machine, it wouldn't work even though the password was correct.
And if that doesn't work try to add:
console.log(req.body);
console.log(user);
To /routes/auth.js (roughly on line 17), and show me the output.
I had the same things and the reason was because the type of data in postman were text and not Json
and how can I encrypt that data sent and received from the server? Anyone can enter my app with a fake name and password just by changing the server response from ok:false to ok:true. This can be easily done using burpsuite
Great video. Thank you so much bro.
Glad it helped
Awesome video, thanks
Glad you liked it!
Thank you brother.. nicely explained.
Glad you liked it
video is great ..but yeah you could have explained more on the auth rote and auth.js , keep creating awesome videos and subscribers will turn up......in large numbers....
would you have to login again after 15 minutes?
The short answer is yes. So I would recommend having some logic on the client-side that would refresh the token, so the user wouldn't have to sign in every 15 minutes.
Awesome video!! I'm in the same as age as you. Really respect!!
Thanks
How to handle user is deactivated after generate jwt token, that token is valid for 15 mins, how we handle
That's a good question, the simplest thing to do is to shorten the time from 15 minutes to 5 minutes, that still doesn't solve the problem. But if you really want to fix it you could always do some extra checks on the server side, to make sure that the person actually has access.
That could be done by including an ID in the JSON web token and then checking if the user still has access or not. So even if the token is still valid the check would still ensure that deactivated users wouldn't be able to access the platform.
@@VincentLabStudio there is any other options are available to check that user is active or not? with out database checking
Wherever you are storing the state that the user is disabled that's where you want to check. So if you're not using a database you don't have to be using a database, hope it makes sense.
Here's some pseudocode:
/routes/auth.js
...
// Dummy data
const users = [{ enabled: false, email: "vincent@vincentlab.net", password: "$2b$15$zqY2Q4eOoGzFpZkHJz9HS.BSfXc/HM2E/yTWa1awFmTMgN2bE72Uu", roles: ["admin", "editor", "viewer"] }];
// Get to user from the database, if the user is not there return error
let user = users.find(u => u.email === req.body.email);
if (!user) throw new Error("Invalid email or password.");
// Maybe you could return a nice error message here
if(!user.enabled) throw new Error("User is deactivated.");
// Compare the password with the password in the database
const valid = await bcrypt.compare(req.body.password, user.password)
if (!valid) throw new Error("Invalid email or password.");
...
Bcrypt hashes the password, not encryption.
You don't explain the main drawback with JWT. How do you revoke tokens?
they will no longer work after a duration rendering them useless??
Thanks Again bruh.
No problem
@@VincentLabStudio Can you make video about MayaJS?
@@KRAMDROIDTECH It seems like something that's not too popular, so I can't promise anything. But I will add it to my to do list.
Can we have part 2 pls?
baba ganoush
First :D