After initial user authentication. JWTs can be used for verification at REST API endpoints. In this tutorial, you will learn how to issue access and refresh tokens (JWTs), and also the recommended way to issue these tokens for security concerns. There will also be suggestions for storing these tokens in your frontend apps. If you are just starting out with Node.js and Express, I suggest you start at the beginning of the Node.js for Beginners tutorial series here: th-cam.com/play/PL0Zuz27SZ-6PFkIxaJ6Xx_X46avTM1aYw.html
I've been following your tutorials on Node, Express, and working my way to Mongo for my project this week. I've told my professor about how helpful your videos are and I've been spreading the word to my classmates. I'm surprised you don't have more views on these tutorials. Thank you for your help!
I just wanted to say I appreciate you and what you do. Your videos are well explained, very thorough, but also digestible. Some instructors get a bit too technical, or lack enough technicality to fully understand what is happening. Yours are right in the pocket. Thank you, kind sir. You have provided a lot of clarification for me.
be very careful when testing this specific implementation with nodemon vs a normal server. nodemon restarts after any file changes, including changes to models\users.json. This allows each function to get the updated state of refresh token. If you run this without nodemon, your refresh and logout functions will reference old versions of the users.json data that do not include the refresh token from the auth. This causes some unwanted behavior that took me quite a while to catch. As always, thanks @DaveGrayTeachescode for another great and comprehensive lesson
How were you able to solve this. Instead of using require for the user.json file which will only load the file at compile time, you could use fs.readfile which will allow it load at runtime.
I usually stay away from tutorials but the content you post is insanely good, I have actually learnt a lot from your channel. Since I discovered it my skills with javascript have improved a lot. Thank you so much
This is masterpiece! 😍 I've thanked on all videos of you I've watched in the comments, and I will do it again on this one because you deserve it. Please keep creating content, I'm seriously worried you might lose interest in it at some point and we lose more content created by you, because you're so good.
I watched many ttorials about jwt because I worked with fullstack php many years and I dont understand rest api so good and This tutorial is where really I did understan about refreshtoken. Thanks
For anyone who doesn't know, if you add secure: true in cookie options, you could only receive cookies on the login route, and in postman couldn't even receive cookies. So test before you add that option.
Dave in the timeframe 34:00 you are checking the founduser name with the decoded username. I feel it is unnecessary because the cookie contains digital signature which can be regenerated by using the header, payload and secret key present only in the server. The verify method would fails if the cookie signature and generated signature doesn't match. what do you mean by tampering.
Thank you Dave. I read through all the comments and your responses to the questions asked which adds more to what has been learned in the video. Thanks again.
21:19 why you set req.user ? In verifyJWT we are just verifying the access token . If it verified then move forward or else error occur. So for what you set req.user to decoded.UserInfo.username?
Hi Dave, this is by far far one of the best JWT Authentication videos that I have seen on TH-cam. I was wondering if you have created a frontend for this project. I am interested to know how one would incorporate the refresh route for a seamless experience if for example, I was on a user page that expired how would I refresh the token and regain access to my session without leaving the page? - many thanks
Great question, Melvyn! And yes, I have very recently. Here is my React Login series that uses the REST API from this Node JS series as the backend: th-cam.com/play/PL0Zuz27SZ-6PRCpm9clX0WiBEMB70FWwd.html 🚀🚀🚀🚀
When I test the refresh route at 38:45 I'm getting a 401 unauthorized response with no cookies available. I've followed along with the first 40 minutes of this tutorial line by line from scratch several times and the refresh route keeps failing. So I also cloned the repo, installed packages, created the .env file, and I still get stuck testing the refresh route with a 401. Dave is the GOAT of youtube coding tutorials, but this one makes me want to run into traffic. I've sunk in far too many hours on this. MOVING ON.
Even as a non-professional I am learning a lot of things that I was curious about like, how cookies work. when you code something all the details are exposed much better than reading an article.
quick question at 45:38 what would happen if the person being iterated through in the database doesnt have a refresh token yet? would the person be filtered through anyway?
Thank you very much. 39:16 - I wonder why the refresh doesn't work for me, no matter what. When I call the refresh router with GET - The console logs the same cookie again and again (it doesn't change like in your code) And instead of Status: 200 OK, I get - Status: 403 Forbidden. Furthermore, I did look very very careful for a long long time that our codes are similar. (When I copied your folder and ran your completed code from scratch than it is immediately failed with MODULE_NOT_FOUND message)
Hi Louis - I do not have MODULE_NOT_FOUND message here. If you used my code, did you install the npm package dependencies? Those modules are needed to run the code. You should run: npm update ...that will install the npm package dependencies that are listed in my package.json file.
@@DaveGrayTeachesCode Thank you for trying to assist... (1) Regarding my code, after manually copied yours, It is only respond with a "Forbidden" error. What might be the issue? (This is not respond with Status: 200 OK and replacing the cookie "hash number" with every refresh like in your code) (2) Regarding your code (including npm update), logged on the console after running (and crashing) : " Error: secretOrPrivateKey must have a value at Object.module.exports [as sign] (D:\Node-js\express_jwt-main ode_modules\jsonwebtoken\sign.js:107:20) at handleLogin (D:\Node-js\express_jwt-main\controllers\authController.js:21:33) [nodemon] app crashed - waiting for file changes before starting... "
@@shineLouisShine looks like you did not create a .env file that holds the secret keys for your access and refresh token creation. Dot env files are not included in Github repositories so you need to create your own. I believe I show how to do this during the video.
@@DaveGrayTeachesCode Wow, I must admit. this is very frustrating. As to my manually written code - I have no idea what is wrong. I certainly wrote the entire code including "process.env.ACCESS_TOKEN_SECRET". Yet, my code isn't respond as your. As to "copypasting" your code, The server doesn't even get connected, only throw this Error: secretOrPrivateKey must have a value. Plus, obviously, each "env" in the code does appear in its correct position, So I'm not entirely understand your kind instruction. So.... I'm completely lost. Totally, desperately, lost.
(..I don't know how have I missed this segment.. 🤦♂..from 04:45 ) Wow, this is a fascinating deep complicated topic. Thank you for this lesson. There's much much more to read and dig. I must admit, that even after creating the tokens - Yet the refreshing of random cookies one after another such as at your representation - Doesn't work. Should I write anything at the headers fields of Thunder Client? Any key-value pair? Do you have any thought what might be the reason of which it doesn't work yet..?
Thanks for your videos... I learned a lot from your videos. My thunder client didnt work as per your video. After logging in and getting the access token and the refresh token cookie. when i tried to do the /refresh, the cookie wasn't send together. I got empty cookie. When i use postman, its the same case but i can manually add the refresh token cookie into the request and it works. REALLY appreciate your video, one of the best video out there.
Hey Dave, Thank you for putting this video with great explanation 👌 I have a question, why did you put `req.user = decoded.username` (21:30)? Since we are not using the username from the request in employeesController functions, should we put decoded username in the request? Please let me know if I am missing something
Thank you very much again. 59:20 - Is it possible that after the last changes which have been made to the code - The "GET refersh" call is no loger refresh the cookies, and respond only with "401 Unauthorized"..?
No, everything works for me at that point. Insure your refresh token is set to last long enough that it is not expiring. Are you logging the value of the refresh token when it is received at that endpoint? That will tell you if it is really receiving a value or not. When you have a problem, you have to eliminate each possibility one-by-one until you find the cause before it can be fixed.
At 23:00 while trying to test auth route after protecting with token, I'm getting an error. Error: secretOrPrivateKey must have a value at module.exports [as sign] (C:\GemReactDemo\server ode_modules\jsonwebtoken\sign.js:105:20) at handleLogin (C:\GemReactDemo\server\controllers\authController.js:21:33)
@@DaveGrayTeachesCode hey Dave thanks for replying. I triple checked each letter of the code to no avail. However the error resolved itself when I console.logged access and refresh tokens. Idk why it started working but it did. Left me confused as hell
@@DaveGrayTeachesCode HI Dave, I'm getting status 401 when I try to generate refresh token after generating access token. I'm unable to generate refresh token. Please help.
Firstly, congratulations on your clear, detailed and brilliantly explained tutorials. You have rare communications skills. I am working with Node.js Express and MySQL. I have come across express-session and express-mysql-session that store user credentials server side rather than in the users browser as with JWT. Could you develop tutorials on these packages please?
What confuses me most is how to store and work with the refresh tokens in my database (Postgres). My plan is to allow multi-login from different devices for the same user, so my idea is to create a refresh token for each device the user tries to log in with. Each refresh token belongs to a unique device, so I don't care which user belongs to it. That's why my plan is to create a refresh token table with no user references. When a user logs out, I simply remove the respective refresh token from the database and don't care if they are still logged in on other devices. Interesting notes/tips: 1) If a user deleted their cookie, you would end up with "dead tokens" that never get removed from the database. That only applies to multi-login and shouldn't really be a problem though. 2) Deleting all refresh tokens from the database forces all users to relog-in. Same when you change the refresh token secret. Don't do that, unless you have a good reason. 3) Hashing the refresh tokens before storing them in your database improves security. Similarly how you'd store passwords hashed and not in plaintext. 4) bcrypt stores the salt in the generated hash, so you don't need to store salts in your database. 5) You can check if a refresh token expired by catching "TokenExpiredError". Since it's a valid token (just expired), you can safely call jwt.decode(...) to get the username and other information. Not sure where I would need that, but maybe that helps some of you. Edit: Okay, I just realised that when you compare your refresh token with the database (refresh token hash), you run into the problem of not knowing which salt to use for hashing. You either use the same salt all the time, which makes hashing irrelevant, or you store a user reference for each refresh token hash so you know which entries to look at. Then check each hashed refresh token against the provided refresh token and see if one of them matches... Something feels wrong with that approach though, so for the time being, I'll just save the refresh tokens in plaintext. Edit2: Another reason to store the user id with the refrehs token is that when they change their password, we need to invalidate all existing refresh tokens for that user. Otherwise they stay logged in from their other devices as if they never changed their password. It can also be useful to know all user's refresh tokens if you implement some kind of "logout from all devices" functionality. Generally, you need to store the user id if you want to be able to improve security. Without user id, you'd need to decode all refresh tokens and check the user, which is extremely inefficient.
In 38:55 when i hit send for the /refresh route i get a response of "unauthorizd". I tried logging the request.cookies.jwt (in the handleRefreshToken) and its undefined. For some reason the cookie is not automatically sent on the request. Moreover when i use the /auth route i do see the accessToken and the cookie (with the refresh token in it) what could be the problem?
Sounds like you are not sending the cookie with the token to the refresh route. You don't describe how you are trying to send it. Fetch has a credentials option. Axios has withCredentials. Maybe you need to set that.
@@DaveGrayTeachesCode thank you for the respond. You said we don't need to send something in the body or auth in the /refresh because the cookie is sent in every subsequent request of the user. In my case after I go for /login I can see in the response the access token and the cookie. But then when I go for /refresh I'm unauthorized because the request.cookies is undefined, so it's send an error. I overcame this adding the cookie inside the /refresh header, but I don't understand why it doesn't happen automatically like in your code, which btw is exactly like mine.
hi, i got the same error, did you fix it? also in verifyJWT file when we check req.headers["authorization"] i got undefined. is this happen to you too?
i have few questions 1 - why did you use req.user = decode.username at 21:24 2- can you provide the front end code please if possible everything else was good but took long to understand
1) We use the jwt.verify method to decode the content inside of the token. One part of that content is the username. We can access it by referring to decoded.username. All of the content is in the decoded object. 2) There is no specific frontend code here. This is a separate backend REST API. One or more frontend applications could access it by making requests.
Hey dave great tutorial ..i seem to run into a problem . while executing the /refresh there seems to be a problem .The refresh toekn doesnt match ...its stored correctly in the users,json file but in the refreshController during the .find(refreshtoken ===tefresh token) ....the previous jwt.cookie which was stored in user.json is somehoe being compared and not the latest token why was updated during /auth...any idea why.
when we send a get/post request to the protected API we need to set the bearer access token in the cookie so it will be stored in the cookies and vulnerable to XSS or crsf attacks or not like that? what we gained by sending it from the login/refresh API using JSON and storing it in the memory then if we send it back using an authorization bearer token to the API? I'm confused!
Hy Dave, I'm stuck in verifyJWT controller, I'm not getting authHeader from the req.headers['authorization']. Any help would be much appreciated please
Fetch and Axios are usually in frontend apps and this video is about Node.js and the backend REST API. I do cover fetch with async / await here: th-cam.com/video/VmQ6dHvnKIM/w-d-xo.html
Hi Dave, I have a question, why do I have to save the token to database? How is that helpful? because you are clearing it from the database, when you created the logout middleware. We can just clear the cookies using the clearCookies as you have done and again we are resetting it to empty string. And is this how authentication done in micro service applications? Or do we pass the token in authorization header in order to access the protected routes? PS - Thanks for making these authentication and authorization series. Loving it. 😍😍.
You don't have to save the refresh token to the database. In fact, many do not and say a benefit of JWT is being "stateless". However, if you want to immediately remove access from someone holding a token, you need to track it. I follow this series up with a JWT Rotation and Re-use Detection video where tokens are also tracked. All in all, more than one JWT strategy exists. Your preference on which to apply.
@@DaveGrayTeachesCode Thanks a lot for the suggestion and I will look into that as well. Thanks for making such a good series. I have been struggling with the authentication part for a long time. This is really helpful. Hope you have a good day. 😊
Great video as always, one question: why we are not saving Access Token in HTTP only Cookie too? then we don't need to attach it to header in front-end. I'm just curious. is there any security reason? becuase it will make it a lot easier for front-end
Good question! If you are only sending the access token back and not wanting to pull any other data from it, your suggestion could work. If other data is sent inside the access token, JavaScript cannot access a secure httpOnly cookie.
Thank you very much. 58:09 - I've checked it : By adding "secure: true" - Refreshing the access token is getting responded with: "401 Unauthorized". Once you delete "secure: true" from authController's res.cookie - Refresh works properly. (And the access token is refreshing with every call to "GET refesh". Do "res.cookie(secure: true)" and refreshing (access token) call- contradict each other?
They do not contradict each other. secure: true means the URLs must start with https - but in our development environment, our URL starts with http - not https. That is why you must remove secure: true in development.
This is an awesome video Dave. Many thanks to you! I do have a question as well, what if we want to make the API accessible to the public and also enable validation through cookies? The CORS gets in the way
You could make _some_ endpoints open to the public and apply JWT auth to the other endpoints. Concerning CORS - which is not part of the JWT auth - you need to decide upfront if open to the public or not. Usually, a publicly available REST API would be created separately from anything that needed to be secure. You may want to Google to see if anyone has mixed the two - but I don't advise it.
Thank you for the excellent video. I have two questions please: 1- Can we depend only on refresh token without the need of generating the access token? 2- Can we depend only on a session token (without the need of jwt) ?
You can configure different JWT strategies including a one token approach. It is more often the access token only in that case. You can use a session approach instead of JWTs.
Is it bad practice to check in the main App.jsx if the access token has expired? (since App.jsx is the highest componente in my react app). Since some routes/places on my web won't have a verification to check if the access token is invalidated. Is doing this bad for performance or something like that?
hello, when my token is generated and put in cookie, this one is not recovered when I do a refresh which means that I am blocked at this stage... can you help me?
@Dave Gray, thks for those videos. It help a lot. However I ve got a question. Why do you put the refresh token in the database ? I've seen lot of tutorial about this subject and I ve Never seen this. Thks for your answer :)
Good question! Yes, many consider a big advantage of JWTs is their "stateless" nature which does not require storage in a database. It is a preference of strategy and can be useful for refresh token re-use detection and rotation as I demonstrate in a later video in this playlist.
@@aurelienchevillotte2874 the approach you use is preference. Some prefer re-use detection as they believe it is more secure - so opinions and approaches vary. If you do not track a token, you cannot immediately remove access - it must expire.
Why do we need access token? Can't we use the refresh token itself? I did not understand that at all. Isn't it enough if we extend the validity period of the refresh token and send it in the header of every request and check it in the backend?
That usually refers to not storing it in the backend database - which is just one approach because it does not have to be stateless. For example, tracking tokens for re-use detection and rotation. However, you are referring to the frontend. If you want to be able to log back in after a refresh, you'll need to store it somewhere like a secure httpOnly cookie or localStorage - but the latter is not secure.
@@DaveGrayTeachesCode Thank you for your reply and detailed quality explanation. Just one question- is that cookie effectively set in the backend (rest api in this case) or is it just packaged in the backend to be actually set and used in the front end?
hi dave i am getting this warning "this attemp to set a cookie via set cookie was blocked by user preferance" in incognito mode how can i handle this?? if not handle it will be be fail in incognito mode
if someone got issue at 24:05 and got this error message: Error: secretOrPrivateKey must have a value at at Object.module.exports [as sign] I find on google a fix by adding string 'process.env.ACCESS_TOKEN_SECRET' 'process.env.REFRESH_TOKEN_SECRET'
Excellent content, u are very much unique in teaching different scenarios and I’m so impressed , your channel teaches real-time scenarios, create a Udemy courses will be great 👍 , one question can you do a oauth authentication on node, and when do frontend should call refresh token api
Thank you, Mahendra! I would need to dive deeper into specific docs for OAuth, but with my understanding, I see no reason what Node.js could not do that. To understand when the frontend will call the refresh token, my React login playlist applies all of that knowledge with the Node.js backend you are building in this series: th-cam.com/play/PL0Zuz27SZ-6PRCpm9clX0WiBEMB70FWwd.html
Help me understand something. Say I authorize by hitting the auth endpoint, get a jwt and a refresh token, and the jwt from auth gets stored in memory in my app. Later, I request a protected endpoint, say a list of employees. I send the api request to get the employees, and that endpoint determines I am expired and therefore grabs a new auth token, I obviously need to get that new auth token from the response to store in my application. Does that mean that every request to every protected endpoint has to return an auth token, which is either the existing one that hasn't expired, or the one that was created from the refresh token?
Hello dave, may i know why you are storing refresh token inside the database? i don't think we need to store it. also what we should do after the refresh token expires
If an admin wants to remove access before the token expires, the database reference is helpful. Your 2nd question - you need to let the token expire at some point which will require the user to log in again. If not, you are granting indefinite access.
I can only guess about your code. Please compare to my source code for differences. Source code is available at the course resources link in the description.
thnks for the video Dave, i had a question what if i want to revoke a user from accessing secure resources from API what would i need to do ? just remove that refresh token of user from DB immediately ?
Yes. If using user roles, remove or disable those, too. A short lived access token - 15 minutes for example - would likely expire soon enough but also applying user roles will allow you to remove access faster.
@@DaveGrayTeachesCode it seems like i need to create another middleware that checks for roles and perform this checking over there , right now its just token verification as you told in the video.
Great tutorial, thanks a lot. I hava just one question, why don't you use Passport JS for authentication? I say that because I saw Passport JS is frecuently used for this
It's been a while since this video came out but i have some questions. Im doing the also the frontend for my application, so, in order to acces the api i have to set the header authorization with the authtoken. I'm doing it with -> axios.defaluts.headers["authorization"] = "Bearer " + res.data[authToken], I suppose this is not the rigth way on doing this, because it seems wierd to manually add the "Bearer " Also, when should I call refreshAuthToken? i understand it gives me a new auth token but in a frontend app when should you call that?
Good questions, and many of these are answered in my frontend React Login series: (th-cam.com/play/PL0Zuz27SZ-6PRCpm9clX0WiBEMB70FWwd.html) ...but briefly, yes, you do set the Bearer word and token manually. I show how to do this with axios for the access and refresh tokens in the React series.
Not unless you are storing it. Many do not store JWT tokens as they wish to keep that process "stateless". However, I do store some tokens in this series because I continue on to show a strategy that applies token re-use detection.
Hi Dave, I'm subscribing you from Turkey and really appreciate for your excellent contents. I just want to ask something. When I create the refreshTokenController and add the logic like you did, I'm registering, and having accessToken from /auth route and when I send a request to /refresh route it returns 401 Unauthorized. I thought maybe I missed something you did so I've downloaded the code from your repository. And I'm facing with the same result. What can I do about that? Thanks a lot!
It depends on what you are using to test your endpoints with. In Postman, after you receiving the secure httpOnly cookie with the refresh token, you need to go in and remove the secure: true flag for dev testing. This is because our local dev environment uses http and secure expects https. Or you could just remove the secure: true from the cookie in the code during development - but remember to put it back before deploying.
@@ugurgunes95 you set secure: true in the code when you create the cookie. I can't remember if ThunderClient lets you edit the cookie after you receive it or not. In this series, I remember noting that I removed secure: true for testing with ThunderClient.
Thank you very much for this awesome tutorial, Dave. I have a question though. We only delete refresh token when user logs out. Does that mean "if some bad guy has access to the user's access token, they still can access protected route for a while before it expires"?
The access token should only be stored in memory (state) on the frontend and should also have a short expiration (15 to 60 minutes - set to preference). In theory though, yes, if someone steals an access token and it is not expired, it will provide access. The undeniable truth: Nothing is 100% secure in the frontend.
That refreshToken thing still confuses me. Lets say realtime, and the access token expires in 15 mins, im an admin and can access all the user information, but when the token expires after 15 mins, it obvi that its gonna be 403 even for the admin. in dev, we could manually send the login creditials again, acquire a new access token, paste it in the bearer section and call for the users info again, it gonna show up eventually. But how will we handle this in real time, how will the access token gonna sit automatically and persist when calling these apis from the front end ?
You can learn all about the frontend strategy and how the refresh token is used to persist a login in my React Auth playlist: th-cam.com/play/PL0Zuz27SZ-6PRCpm9clX0WiBEMB70FWwd.html
Hey Dave! How is JWT access token invalidated following user logoff? I can see that refresh token is removed but JWT access token remains valid for some time.
JWT tokens are often used in a stateless manner, and that is to say, they are not tracked at all but just allowed to expire. I went ahead and tracked refresh tokens in this series so I could later talk about token re-use and rotation, but it is not necessary in many instances. The access tokens should expire in a relatively short time as discussed in the video.
After initial user authentication. JWTs can be used for verification at REST API endpoints. In this tutorial, you will learn how to issue access and refresh tokens (JWTs), and also the recommended way to issue these tokens for security concerns. There will also be suggestions for storing these tokens in your frontend apps. If you are just starting out with Node.js and Express, I suggest you start at the beginning of the Node.js for Beginners tutorial series here: th-cam.com/play/PL0Zuz27SZ-6PFkIxaJ6Xx_X46avTM1aYw.html
So this is how a senior dev works and explains things. Simply amazing. Thank you for these videos.
You're welcome! 💯
Learnt React from Dave and I contributed to one of my friend's project... bro was amazed at the way I did things.... I now feel like a senior dev
I've been following your tutorials on Node, Express, and working my way to Mongo for my project this week. I've told my professor about how helpful your videos are and I've been spreading the word to my classmates. I'm surprised you don't have more views on these tutorials. Thank you for your help!
Thank you, Ali! 🙏🙏
Dude, this is by far the best tutorial series I have seen. Unparalleled quality. Thankyou!
I just wanted to say I appreciate you and what you do. Your videos are well explained, very thorough, but also digestible. Some instructors get a bit too technical, or lack enough technicality to fully understand what is happening. Yours are right in the pocket. Thank you, kind sir. You have provided a lot of clarification for me.
be very careful when testing this specific implementation with nodemon vs a normal server. nodemon restarts after any file changes, including changes to models\users.json. This allows each function to get the updated state of refresh token. If you run this without nodemon, your refresh and logout functions will reference old versions of the users.json data that do not include the refresh token from the auth. This causes some unwanted behavior that took me quite a while to catch. As always, thanks @DaveGrayTeachescode for another great and comprehensive lesson
How were you able to solve this. Instead of using require for the user.json file which will only load the file at compile time, you could use fs.readfile which will allow it load at runtime.
I usually stay away from tutorials but the content you post is insanely good, I have actually learnt a lot from your channel. Since I discovered it my skills with javascript have improved a lot. Thank you so much
Awesome! Thank you! 💯
hey dave this series is really helpful. the way you split things into routers and middleware has been eye-opening. so simple
Glad it helped!
This is masterpiece! 😍 I've thanked on all videos of you I've watched in the comments, and I will do it again on this one because you deserve it. Please keep creating content, I'm seriously worried you might lose interest in it at some point and we lose more content created by you, because you're so good.
Thank you! I'll keep going! 💯🙏
I’m so happy to get my account back with help of this professional teams (name on my channel ) kidney massage him now 😮
I watched many ttorials about jwt because I worked with fullstack php many years and I dont understand rest api so good and This tutorial is where really I did understan about refreshtoken. Thanks
Glad it was helpful!
dave calling out whitelist was the perfect endcap to this great video. dave, my man, youve done it again... another fantastic video
Glad you enjoyed it!
For anyone who doesn't know, if you add secure: true in cookie options, you could only receive cookies on the login route, and in postman couldn't even receive cookies. So test before you add that option.
thank god I came across this comment. helped a bunch ahhah thanks
Thank you, i got confused in this part
Thanks it helped. But how do you deal with that in the production enviromment
Wrong, for that You need to set PATH in cookie
Would love to see an updated version with Typescript and maybe with a relational database. These videos are literally the best.
Dave in the timeframe 34:00 you are checking the founduser name with the decoded username. I feel it is unnecessary because the cookie contains digital signature which can be regenerated by using the header, payload and secret key present only in the server. The verify method would fails if the cookie signature and generated signature doesn't match. what do you mean by tampering.
Hi Dave, Thanks again for sharing this high quality content. Your explanations are excellent.
You're welcome!
Thank you Dave. I read through all the comments and your responses to the questions asked which adds more to what has been learned in the video. Thanks again.
Great to hear! You're welcome!
Thanks Dave, you’re an awesome teacher. Keep it coming please!
Thanks, will do!
21:19 why you set req.user ? In verifyJWT we are just verifying the access token . If it verified then move forward or else error occur. So for what you set req.user to decoded.UserInfo.username?
probably the most detailed series on the youtube, although really wish you used ts
Thank you for nodejs playlist, Your clear explanations and practical examples made the learning process engaging and effective.
Thanks so much, I just finished your node js course so I was going back to some concepts, I don’t thank you enough
You're welcome!
Hi Dave, this is by far far one of the best JWT Authentication videos that I have seen on TH-cam. I was wondering if you have created a frontend for this project. I am interested to know how one would incorporate the refresh route for a seamless experience if for example, I was on a user page that expired how would I refresh the token and regain access to my session without leaving the page? - many thanks
Great question, Melvyn! And yes, I have very recently. Here is my React Login series that uses the REST API from this Node JS series as the backend: th-cam.com/play/PL0Zuz27SZ-6PRCpm9clX0WiBEMB70FWwd.html 🚀🚀🚀🚀
@@DaveGrayTeachesCode Fantastic! - thanks again
thanks for putting up these videos dave. hopefully the playlist will be a library for node videos that i can come back to if i need a refresher
You're welcome! Glad I could help. 💯
This is a very valuable video for me. I've been trying to understand how the aT and rT works. Thanks very much
When I test the refresh route at 38:45 I'm getting a 401 unauthorized response with no cookies available. I've followed along with the first 40 minutes of this tutorial line by line from scratch several times and the refresh route keeps failing. So I also cloned the repo, installed packages, created the .env file, and I still get stuck testing the refresh route with a 401. Dave is the GOAT of youtube coding tutorials, but this one makes me want to run into traffic. I've sunk in far too many hours on this. MOVING ON.
If you set the cookie secure: true, you must use https. Local dev usually just uses http - other comments here on this, too.
Even as a non-professional I am learning a lot of things that I was curious about like, how cookies work. when you code something all the details are exposed much better than reading an article.
quick question at 45:38 what would happen if the person being iterated through in the database doesnt have a refresh token yet? would the person be filtered through anyway?
Again great video. Thank you very much Dave.
Hi Dave. Thank you very much. This series have helped me so much.
Glad I could help! You're welcome! 🙏💯
watched from start of the playlist till this video awesome detailed tutorial, thank you very much
You're very welcome!
43:31 If there's no JWT cookie during logout, shouldn't we send one of 400 codes? Like 401- Unauthorized?
It was a great video, thanks Dave !
Very welcome!
Wow. Excellent video. Great job. Thanks a lot for doing these tutorials.
Thank you! 💯
Thanks teacher Dave for making this api totorial availabe,
Thank you very much.
39:16 - I wonder why the refresh doesn't work for me, no matter what.
When I call the refresh router with GET -
The console logs the same cookie again and again (it doesn't change like in your code)
And instead of Status: 200 OK, I get - Status: 403 Forbidden.
Furthermore, I did look very very careful for a long long time that our codes are similar.
(When I copied your folder and ran your completed code from scratch than it is immediately failed with MODULE_NOT_FOUND message)
Hi Louis - I do not have MODULE_NOT_FOUND message here. If you used my code, did you install the npm package dependencies? Those modules are needed to run the code. You should run: npm update ...that will install the npm package dependencies that are listed in my package.json file.
@@DaveGrayTeachesCode Thank you for trying to assist...
(1)
Regarding my code, after manually copied yours,
It is only respond with a "Forbidden" error.
What might be the issue?
(This is not respond with Status: 200 OK and replacing the cookie "hash number" with every refresh like in your code)
(2)
Regarding your code (including npm update), logged on the console after running (and crashing) :
"
Error: secretOrPrivateKey must have a value
at Object.module.exports [as sign] (D:\Node-js\express_jwt-main
ode_modules\jsonwebtoken\sign.js:107:20)
at handleLogin (D:\Node-js\express_jwt-main\controllers\authController.js:21:33)
[nodemon] app crashed - waiting for file changes before starting...
"
@@shineLouisShine looks like you did not create a .env file that holds the secret keys for your access and refresh token creation. Dot env files are not included in Github repositories so you need to create your own. I believe I show how to do this during the video.
@@DaveGrayTeachesCode Wow, I must admit. this is very frustrating.
As to my manually written code - I have no idea what is wrong.
I certainly wrote the entire code including "process.env.ACCESS_TOKEN_SECRET".
Yet, my code isn't respond as your.
As to "copypasting" your code,
The server doesn't even get connected, only throw this Error: secretOrPrivateKey must have a value.
Plus, obviously, each "env" in the code does appear in its correct position,
So I'm not entirely understand your kind instruction.
So.... I'm completely lost.
Totally, desperately, lost.
(..I don't know how have I missed this segment.. 🤦♂..from 04:45 )
Wow, this is a fascinating deep complicated topic.
Thank you for this lesson.
There's much much more to read and dig.
I must admit, that even after creating the tokens -
Yet the refreshing of random cookies one after another such as at your representation -
Doesn't work.
Should I write anything at the headers fields of Thunder Client?
Any key-value pair?
Do you have any thought what might be the reason of which it doesn't work yet..?
You are awesome. Great videos with a rich content.
I'm a bit late to this back end party, everything works accept I had to use Postman for the refresh and logout routes.
Thanks Dave. 🌮🌮🌮
Thanks for your videos... I learned a lot from your videos. My thunder client didnt work as per your video. After logging in and getting the access token and the refresh token cookie. when i tried to do the /refresh, the cookie wasn't send together. I got empty cookie. When i use postman, its the same case but i can manually add the refresh token cookie into the request and it works. REALLY appreciate your video, one of the best video out there.
I just finished your next video on the Roles. you did mentioned that secure need to be removed. Thanks !!1
Sir your courses are the best
Thank you!
Hey Dave,
Thank you for putting this video with great explanation 👌
I have a question, why did you put `req.user = decoded.username` (21:30)? Since we are not using the username from the request in employeesController functions, should we put decoded username in the request?
Please let me know if I am missing something
Hey Dave!
Thank you very much .
Welcome!
What a great tutorial. Thank you. I learned a lot
You're welcome! 💯
Great Explanation 😊
Glad you liked it!
Thank you very much again.
59:20 - Is it possible that after the last changes which have been made to the code -
The "GET refersh" call is no loger refresh the cookies, and respond only with "401 Unauthorized"..?
No, everything works for me at that point. Insure your refresh token is set to last long enough that it is not expiring. Are you logging the value of the refresh token when it is received at that endpoint? That will tell you if it is really receiving a value or not. When you have a problem, you have to eliminate each possibility one-by-one until you find the cause before it can be fixed.
Wow, very well explained, thank you!
You're welcome!
Thanks a lot. You are gifted for teaching.
Thank you!
30:00 I don't understand which part in the refresh token allows it to create another access token when it is expired, can anyone explain for me?
At 23:00 while trying to test auth route after protecting with token, I'm getting an error.
Error: secretOrPrivateKey must have a value
at module.exports [as sign] (C:\GemReactDemo\server
ode_modules\jsonwebtoken\sign.js:105:20)
at handleLogin (C:\GemReactDemo\server\controllers\authController.js:21:33)
The error indicates you do not have a value for secretOrPrivateKey. Go back and find where I set that.
@@DaveGrayTeachesCode hey Dave thanks for replying. I triple checked each letter of the code to no avail. However the error resolved itself when I console.logged access and refresh tokens. Idk why it started working but it did. Left me confused as hell
@@DaveGrayTeachesCode HI Dave, I'm getting status 401 when I try to generate refresh token after generating access token. I'm unable to generate refresh token. Please help.
thanks for the tut, quite a good teaching style
You are welcome! 💯
Firstly, congratulations on your clear, detailed and brilliantly explained tutorials. You have rare communications skills. I am working with Node.js Express and MySQL. I have come across express-session and express-mysql-session that store user credentials server side rather than in the users browser as with JWT. Could you develop tutorials on these packages please?
Thanks a lot for your videos! It is really helpful!
You are welcome!
What confuses me most is how to store and work with the refresh tokens in my database (Postgres). My plan is to allow multi-login from different devices for the same user, so my idea is to create a refresh token for each device the user tries to log in with. Each refresh token belongs to a unique device, so I don't care which user belongs to it. That's why my plan is to create a refresh token table with no user references. When a user logs out, I simply remove the respective refresh token from the database and don't care if they are still logged in on other devices.
Interesting notes/tips:
1) If a user deleted their cookie, you would end up with "dead tokens" that never get removed from the database. That only applies to multi-login and shouldn't really be a problem though.
2) Deleting all refresh tokens from the database forces all users to relog-in. Same when you change the refresh token secret. Don't do that, unless you have a good reason.
3) Hashing the refresh tokens before storing them in your database improves security. Similarly how you'd store passwords hashed and not in plaintext.
4) bcrypt stores the salt in the generated hash, so you don't need to store salts in your database.
5) You can check if a refresh token expired by catching "TokenExpiredError". Since it's a valid token (just expired), you can safely call jwt.decode(...) to get the username and other information. Not sure where I would need that, but maybe that helps some of you.
Edit: Okay, I just realised that when you compare your refresh token with the database (refresh token hash), you run into the problem of not knowing which salt to use for hashing. You either use the same salt all the time, which makes hashing irrelevant, or you store a user reference for each refresh token hash so you know which entries to look at. Then check each hashed refresh token against the provided refresh token and see if one of them matches... Something feels wrong with that approach though, so for the time being, I'll just save the refresh tokens in plaintext.
Edit2: Another reason to store the user id with the refrehs token is that when they change their password, we need to invalidate all existing refresh tokens for that user. Otherwise they stay logged in from their other devices as if they never changed their password. It can also be useful to know all user's refresh tokens if you implement some kind of "logout from all devices" functionality. Generally, you need to store the user id if you want to be able to improve security. Without user id, you'd need to decode all refresh tokens and check the user, which is extremely inefficient.
I suggest joining my Discord for bigger discussions like this one: discord.gg/neKghyefqh
This is great! Thank you so much!
Glad it was helpful! And you're welcome! 💯
In 38:55 when i hit send for the /refresh route i get a response of "unauthorizd".
I tried logging the request.cookies.jwt (in the handleRefreshToken) and its undefined.
For some reason the cookie is not automatically sent on the request.
Moreover when i use the /auth route i do see the accessToken and the cookie (with the refresh token in it)
what could be the problem?
Sounds like you are not sending the cookie with the token to the refresh route. You don't describe how you are trying to send it. Fetch has a credentials option. Axios has withCredentials. Maybe you need to set that.
@@DaveGrayTeachesCode thank you for the respond.
You said we don't need to send something in the body or auth in the /refresh because the cookie is sent in every subsequent request of the user. In my case after I go for /login I can see in the response the access token and the cookie. But then when I go for /refresh I'm unauthorized because the request.cookies is undefined, so it's send an error. I overcame this adding the cookie inside the /refresh header, but I don't understand why it doesn't happen automatically like in your code, which btw is exactly like mine.
hi, i got the same error, did you fix it? also in verifyJWT file when we check req.headers["authorization"] i got undefined. is this happen to you too?
you are on god mode, sir !!
🙏🙏
i have few questions
1 - why did you use req.user = decode.username at 21:24
2- can you provide the front end code please if possible
everything else was good but took long to understand
1) We use the jwt.verify method to decode the content inside of the token. One part of that content is the username. We can access it by referring to decoded.username. All of the content is in the decoded object.
2) There is no specific frontend code here. This is a separate backend REST API. One or more frontend applications could access it by making requests.
Hey dave great tutorial ..i seem to run into a problem . while executing the /refresh there seems to be a problem .The refresh toekn doesnt match ...its stored correctly in the users,json file but in the refreshController during the .find(refreshtoken ===tefresh token) ....the previous jwt.cookie which was stored in user.json is somehoe being compared and not the latest token why was updated during /auth...any idea why.
Thank you very much, Dave
You're welcome! 💯
Awesome content!
🙏🙏
when we send a get/post request to the protected API we need to set the bearer access token in the cookie so it will be stored in the cookies and vulnerable to XSS or crsf attacks or not like that? what we gained by sending it from the login/refresh API using JSON and storing it in the memory then if we send it back using an authorization bearer token to the API? I'm confused!
Thank you so much for your videos
Hy Dave, I'm stuck in verifyJWT controller, I'm not getting authHeader from the req.headers['authorization']. Any help would be much appreciated please
I suggest downloading the source code from the link in the description and comparing to yours to find the differences.
Thank you so much. Do you have a starting point for how I can intercept request/response using fetch rather than axios?
Fetch and Axios are usually in frontend apps and this video is about Node.js and the backend REST API. I do cover fetch with async / await here: th-cam.com/video/VmQ6dHvnKIM/w-d-xo.html
Great explanation Dave ..complete this series? ??
Almost! Now we just need a database technology like Mongo or Postgres. Adding MongoDB will complete the MERN stack when combined with React.
Please start new new project mern stack with react with redux
@@DeepakGupta-hj2dv yes, I will be creating projects with this stack.
You are the best
Thank you! 🙏
Hi Dave, I have a question, why do I have to save the token to database? How is that helpful? because you are clearing it from the database, when you created the logout middleware. We can just clear the cookies using the clearCookies as you have done and again we are resetting it to empty string.
And is this how authentication done in micro service applications? Or do we pass the token in authorization header in order to access the protected routes?
PS - Thanks for making these authentication and authorization series. Loving it. 😍😍.
You don't have to save the refresh token to the database. In fact, many do not and say a benefit of JWT is being "stateless". However, if you want to immediately remove access from someone holding a token, you need to track it. I follow this series up with a JWT Rotation and Re-use Detection video where tokens are also tracked. All in all, more than one JWT strategy exists. Your preference on which to apply.
@@DaveGrayTeachesCode Thanks a lot for the suggestion and I will look into that as well. Thanks for making such a good series. I have been struggling with the authentication part for a long time. This is really helpful. Hope you have a good day. 😊
i have never thought about "whitelist" as something racist
Great video as always, one question: why we are not saving Access Token in HTTP only Cookie too? then we don't need to attach it to header in front-end. I'm just curious. is there any security reason? becuase it will make it a lot easier for front-end
Good question! If you are only sending the access token back and not wanting to pull any other data from it, your suggestion could work. If other data is sent inside the access token, JavaScript cannot access a secure httpOnly cookie.
Thank you very much.
58:09 - I've checked it :
By adding "secure: true" -
Refreshing the access token is getting responded with:
"401 Unauthorized".
Once you delete "secure: true" from authController's res.cookie - Refresh works properly.
(And the access token is refreshing with every call to "GET refesh".
Do "res.cookie(secure: true)" and refreshing (access token) call- contradict each other?
They do not contradict each other. secure: true means the URLs must start with https - but in our development environment, our URL starts with http - not https. That is why you must remove secure: true in development.
Thank you so much!
Just to be clear if the backend and frontend are on the same domain we don't need to set the "Same Site: none".
Excellent clarification!
This is an awesome video Dave. Many thanks to you!
I do have a question as well, what if we want to make the API accessible to the public and also enable validation through cookies?
The CORS gets in the way
You could make _some_ endpoints open to the public and apply JWT auth to the other endpoints. Concerning CORS - which is not part of the JWT auth - you need to decide upfront if open to the public or not. Usually, a publicly available REST API would be created separately from anything that needed to be secure. You may want to Google to see if anyone has mixed the two - but I don't advise it.
Thank you for the excellent video. I have two questions please:
1- Can we depend only on refresh token without the need of generating the access token?
2- Can we depend only on a session token (without the need of jwt) ?
You can configure different JWT strategies including a one token approach. It is more often the access token only in that case. You can use a session approach instead of JWTs.
Amazing tutorial
Thank you, Sona!
Thanks Dave
Is it bad practice to check in the main App.jsx if the access token has expired? (since App.jsx is the highest componente in my react app). Since some routes/places on my web won't have a verification to check if the access token is invalidated. Is doing this bad for performance or something like that?
hello, when my token is generated and put in cookie, this one is not recovered when I do a refresh which means that I am blocked at this stage... can you help me?
Verify that you are sending the secure: true flag in the cookie. As noted in the tutorial, I had to remove it as ThunderClient did not recognize it.
@@DaveGrayTeachesCode , It works, Thank you!
@Dave Gray, thks for those videos. It help a lot. However I ve got a question. Why do you put the refresh token in the database ? I've seen lot of tutorial about this subject and I ve Never seen this. Thks for your answer :)
Good question! Yes, many consider a big advantage of JWTs is their "stateless" nature which does not require storage in a database. It is a preference of strategy and can be useful for refresh token re-use detection and rotation as I demonstrate in a later video in this playlist.
@@DaveGrayTeachesCode thanks for your answer. Last question, please, if I don't put refresh token in database does it affect the app security ?
@@aurelienchevillotte2874 the approach you use is preference. Some prefer re-use detection as they believe it is more secure - so opinions and approaches vary. If you do not track a token, you cannot immediately remove access - it must expire.
excellent job sir.
Thank you for the kind words! 🙏
Sir, you are one of the best on the planet. Could you please make a project video on complete MERN stack and posssibly GraphQL ? Thank you
Thank you, TR 🙏 I do have a MERN project in the works. 💯
@@DaveGrayTeachesCode Please update this project with mongoose i.e. MongoDB atlas i.e. Cloud
Why do we need access token? Can't we use the refresh token itself? I did not understand that at all. Isn't it enough if we extend the validity period of the refresh token and send it in the header of every request and check it in the backend?
Refresh token explanation: auth0.com/docs/secure/tokens/refresh-tokens
Access token explanation: auth0.com/docs/secure/tokens/access-tokens
Hello, doesn't setting a refresh token cookie violate the REST Stateless principle in this case?
That usually refers to not storing it in the backend database - which is just one approach because it does not have to be stateless. For example, tracking tokens for re-use detection and rotation. However, you are referring to the frontend. If you want to be able to log back in after a refresh, you'll need to store it somewhere like a secure httpOnly cookie or localStorage - but the latter is not secure.
@@DaveGrayTeachesCode Thank you for your reply and detailed quality explanation. Just one question- is that cookie effectively set in the backend (rest api in this case) or is it just packaged in the backend to be actually set and used in the front end?
hi dave i am getting this warning "this attemp to set a cookie via set cookie was blocked by user preferance" in incognito mode how can i handle this?? if not handle it will be be fail in incognito mode
whats the voice change at 36:50 got me shooked
if someone got issue at 24:05 and got this error message:
Error: secretOrPrivateKey must have a value at at Object.module.exports [as sign]
I find on google a fix by adding string
'process.env.ACCESS_TOKEN_SECRET'
'process.env.REFRESH_TOKEN_SECRET'
Excellent content, u are very much unique in teaching different scenarios and I’m so impressed , your channel teaches real-time scenarios, create a Udemy courses will be great 👍 , one question can you do a oauth authentication on node, and when do frontend should call refresh token api
Thank you, Mahendra! I would need to dive deeper into specific docs for OAuth, but with my understanding, I see no reason what Node.js could not do that. To understand when the frontend will call the refresh token, my React login playlist applies all of that knowledge with the Node.js backend you are building in this series: th-cam.com/play/PL0Zuz27SZ-6PRCpm9clX0WiBEMB70FWwd.html
@@DaveGrayTeachesCode thank you so much 😊👍🙌🏻👏🤝
Help me understand something. Say I authorize by hitting the auth endpoint, get a jwt and a refresh token, and the jwt from auth gets stored in memory in my app. Later, I request a protected endpoint, say a list of employees. I send the api request to get the employees, and that endpoint determines I am expired and therefore grabs a new auth token, I obviously need to get that new auth token from the response to store in my application.
Does that mean that every request to every protected endpoint has to return an auth token, which is either the existing one that hasn't expired, or the one that was created from the refresh token?
Apparently this can be handled with axios interceptors?
Hello dave, may i know why you are storing refresh token inside the database?
i don't think we need to store it. also what we should do after the refresh token expires
If an admin wants to remove access before the token expires, the database reference is helpful. Your 2nd question - you need to let the token expire at some point which will require the user to log in again. If not, you are granting indefinite access.
Hey Dave, thanks for the great tutorial ! I get an undefined req.headers['authorization'] in the verifyJWT middleware. Any hint ?
I can only guess about your code. Please compare to my source code for differences. Source code is available at the course resources link in the description.
Big Thanks!!
BIG Welcome!
thnks for the video Dave,
i had a question what if i want to revoke a user from accessing secure resources from API what would i need to do ? just remove that refresh token of user from DB immediately ?
Yes. If using user roles, remove or disable those, too. A short lived access token - 15 minutes for example - would likely expire soon enough but also applying user roles will allow you to remove access faster.
@@DaveGrayTeachesCode it seems like i need to create another middleware that checks for roles and perform this checking over there , right now its just token verification as you told in the video.
Why do you add random access and refresh token in .env file?
Or what happens if we set the ACCESS & REFRESH token to "" ?
I thought I explained why I did? For "what happens if" questions.. I always say try it :)
Great tutorial, thanks a lot. I hava just one question, why don't you use Passport JS for authentication? I say that because I saw Passport JS is frecuently used for this
Passport JS can be used for auth. Why didn't I use it? It is not the only solution and not what I created the tutorial about.
It's been a while since this video came out but i have some questions.
Im doing the also the frontend for my application, so, in order to acces the api i have to set the header authorization with the authtoken. I'm doing it with -> axios.defaluts.headers["authorization"] = "Bearer " + res.data[authToken], I suppose this is not the rigth way on doing this, because it seems wierd to manually add the "Bearer "
Also, when should I call refreshAuthToken? i understand it gives me a new auth token but in a frontend app when should you call that?
Good questions, and many of these are answered in my frontend React Login series: (th-cam.com/play/PL0Zuz27SZ-6PRCpm9clX0WiBEMB70FWwd.html) ...but briefly, yes, you do set the Bearer word and token manually. I show how to do this with axios for the access and refresh tokens in the React series.
@@DaveGrayTeachesCode On it! Thank you so much!
HI, thanks for video. Great job. Can you tell us about typescript and prisma? thanks.
You're welcome! And thanks for the requests! 🙏
If I were using MongoDB as my database, would I need to add a refreshToken field in the mongoose schema?
Not unless you are storing it. Many do not store JWT tokens as they wish to keep that process "stateless". However, I do store some tokens in this series because I continue on to show a strategy that applies token re-use detection.
Hi Dave, I'm subscribing you from Turkey and really appreciate for your excellent contents. I just want to ask something. When I create the refreshTokenController and add the logic like you did, I'm registering, and having accessToken from /auth route and when I send a request to /refresh route it returns 401 Unauthorized. I thought maybe I missed something you did so I've downloaded the code from your repository. And I'm facing with the same result. What can I do about that? Thanks a lot!
It depends on what you are using to test your endpoints with. In Postman, after you receiving the secure httpOnly cookie with the refresh token, you need to go in and remove the secure: true flag for dev testing. This is because our local dev environment uses http and secure expects https. Or you could just remove the secure: true from the cookie in the code during development - but remember to put it back before deploying.
@@DaveGrayTeachesCode I am using thunder client since I saw it from your videos. In thunder client I couldn’t find how to set secure: true flag.
@@ugurgunes95 you set secure: true in the code when you create the cookie. I can't remember if ThunderClient lets you edit the cookie after you receive it or not. In this series, I remember noting that I removed secure: true for testing with ThunderClient.
@@DaveGrayTeachesCode I'm going to have some research about it. If I find something I'll let you know. Thanks again :)
The secure: true flag for dev testing works right using Postman but not using Thunder Client 😊
Thank you very much for this awesome tutorial, Dave. I have a question though.
We only delete refresh token when user logs out. Does that mean "if some bad guy has access to the user's access token, they still can access protected route for a while before it expires"?
The access token should only be stored in memory (state) on the frontend and should also have a short expiration (15 to 60 minutes - set to preference). In theory though, yes, if someone steals an access token and it is not expired, it will provide access. The undeniable truth: Nothing is 100% secure in the frontend.
That refreshToken thing still confuses me. Lets say realtime, and the access token expires in 15 mins, im an admin and can access all the user information, but when the token expires after 15 mins, it obvi that its gonna be 403 even for the admin. in dev, we could manually send the login creditials again, acquire a new access token, paste it in the bearer section and call for the users info again, it gonna show up eventually. But how will we handle this in real time, how will the access token gonna sit automatically and persist when calling these apis from the front end ?
You can learn all about the frontend strategy and how the refresh token is used to persist a login in my React Auth playlist: th-cam.com/play/PL0Zuz27SZ-6PRCpm9clX0WiBEMB70FWwd.html
Hey Dave! How is JWT access token invalidated following user logoff? I can see that refresh token is removed but JWT access token remains valid for some time.
JWT tokens are often used in a stateless manner, and that is to say, they are not tracked at all but just allowed to expire. I went ahead and tracked refresh tokens in this series so I could later talk about token re-use and rotation, but it is not necessary in many instances. The access tokens should expire in a relatively short time as discussed in the video.