Hope you enjoyed the video! 😁 I also have a really cool and unique course that will teach you way more than this video. You'll learn how to build an actual complex project with React. It's called "Project React" and you can find it at cosden.solutions/project-react. Also, I have a free weekly newsletter called "Import React" with tutorials, news, and cool stuff about React! You can sign up at cosden.solutions/newsletter?s=ytc
The HTTPOnly cookies travel back and forth with every HTTP request and response, just like regular cookies. The only difference is that the browser will not allow the client-side Javascript to access them, which can prevent certain types of attacks.
Great video! The implementation looks really interesting. Could you please share the source code for this project? It would be very helpful for those of us trying to learn and follow along. Thanks!
this one just awesome , please more video about authentication and authorization + a comprehensive one for axios thanks a lot one of the few channels worth subscribing...
“Refresh token is only on the server” this is nonsense. Http only cookies are not on servers, cookies are for clients. The server checks the cookie that is sent with every request to the server. It’s not living on the server. Your video quality is great, but this is a fundamental mistake
Agreed, the refresh token gets sent to the client to be stored as a HTTP-only cookie by the browser and sent on each request (or at least on each request to the path specified by the cookie)
Hello, If we are sending the token in authorization header, then they will be visible to everyone anyways. Why should we not store the access token in session/localStorage?
Great tutorial, but I have one question what if the user refreshes the app before the expiration time if so the token in memory will be undefined so how the server will identify the user in the refresh token call ? as the API request token is undefined even if the user has a valid refresh token?
Even if an attacker gains access to access token, they can’t do much with it because they don’t know the secret used to sign the JWT. The secret is stored server-side and remains hidden, preventing them from forging or tampering with the token
I understand the concept of saving the access token in memory and why it's more secure to keep it there. However, what I don't understand is how the server knows it's "you" who sent the request for a new access token when the app is refreshed. Is it determined by IP address? By browser? What information is sent from the front end to the backend to verify that the user is the correct one for that refresh token to generate a new access token? I need to tell the backend developers what they need to implement for the front end to have a correct flow of the tokens. I would greatly appreciate an explanation of this, as I am struggling to understand how to keep the access token in memory. Currently, I have been saving it in session storage.
Ah, http-only cookies are actually stored locally with a set Cookie. The only thing is that they are not accessible through scripts but on subsequent http requests
I handle it this way. You see, if you're using jwt, you encode user data (e.g: email, roles) to it by passing it as a jwt payload when generating a new token. Same thing with refresh token. The only thing is you store refresh token in database in your user entity before setting it in request cookies. Then when handling the refresh route, you extract refresh token from the cookies and first find a user in the database who has the same refresh token, then you decode it, which will allow you to extract encrypted data(as I said before: email, roles). If the user from the database (one you found via refresh token) shares the same email and roles then it is the same person sending a request for a new access token so you generate new one for him and send it, otherwise you throw an error with 403 status code
I think this is what’s missing in the video. I'm not a backend developer, and I noticed there was no code to save the HTTP-only cookie, so I was left wondering, "What magic is happening here?" I did some further research and I think I understand it now. However, a detailed backend explanation would be very useful so we know exactly what's going on. In the process described, two tokens are created: a refresh token and an access token. The refresh token is sent in an HTTP-only cookie as a header, while the access token is included in the response of the request. The browser automatically saves the cookie when the backend sends it as an HTTP-only cookie, provided that CORS (Cross-Origin Resource Sharing) is properly configured on both the frontend and backend (with credentials allowed). This ensures the cookie is saved and shared with every request. Therefore, if we don't have an access token when a refresh is needed, the refresh token, which exists as a cookie in the browser, will be sent to obtain a new access token. Maybe it was just me who didn’t fully grasp the concept initially and it was obvious from the start, but asking the question and getting answers helped point me in the right direction. Initially I though the HTTP-only cookie existed only in the server which lead me to misunderstandings.
@@HeinerAngarita Hi, if you need a detailed backend code for handling user authentication and authorization, I can provide you with a link to my github repo. I used express js with typescript, prisma, and postgres for the db. And, if you need one for non-relational db such as MongoDb, I have a second repo for that as well. They're nealy identical in terms of handling the business logic, only difference is the way I query the database
Very nice and concise tutorial. However, can you answer my question ?. Should I do authentication myself or use a third party for that ? Also what are the possible vulnerabilities i am exposed to if i do it myself ?
If you store token in state won't it get deleted on page refresh? Then what would you send to the server. So every time the page is refreshed the user needs to relogin?
@@mohamedmaher2981 no, on every initial render we send a request to api/me, which checks the refresh token and sends an access token if there is a valid refresh token.
@@tuanvumaihuynh brother tuanvumaihuynh, damn your name is hard... anyhow, can you please elaborate more on how to do that? is there a name for such implementation?
Hi Codsen, great video! Thanks for all the wonderful content. One burning question I've had is why the frontend is responsible for calling the refresh token endpoint? Since the backend is the one sending the 403 with the Unauthorized error, couldn't the backend be responsible for intercepting that request in the error handler and trying to hit the refresh endpoint? Obviously the RT would need to be sent with every request and not just on the specific refresh token endpoint if that were the case, so the AT and RT would be sent with every request. Any guidance/education on why it's not done all from the backend but rather from the frontend? Is it because now the RT has to be sent with every request? Even with that I would think it's secure because it's still stored in an HTTP-only cookie, but is the concern with a bad actor intercepting the cookie from the request?
Hi, Im no expert but I think it depends. With this approach you are avoiding sending the refresh token in every request, and I think this is important because refresh token being intercepted would be VERY bad for the user. The drawback of this is that every time that you need to refresh the token (you can say around 10 min) the user has to sent 3 requests (1 for trying to do whatever he wants, 1 for refreshing the token when the first request fails and the last one for trying to do again the actual work , this time successfully). I think its a choice between security or reducing that 3 request). In my opinion, those request are not really going to fuck too much your performance and Ive seen that the usual thing to do is as in the video. Hope it helps!
once again a very great and well-explained video like always !! a BIG THANKS from berlin 🖤 all respect for your whole effort producing those video tutorials!
So hard to find instructors like you.Can you add part two explaining how you would add RBAC in this implementation for role based authentication and have private routes and a hint on how to handle this with nextjs 14.We need to understand fully this phrase "Roll you own auth" and not becoming dependant on thirdy party libraries.Thank you
I handle it this way. You see, if you're using jwt, you encode user data (e.g: email, roles) to it by passing it as a jwt payload when generating a new token. Same thing with refresh token. The only thing is you store refresh token in database in your user entity before setting it in request cookies. Then when handling the refresh route, you extract refresh token from the cookies and first find a user in the database who has the same refresh token, then you decode it, which will allow you to extract encrypted data(as I said before: email, roles). If the user from the database (one you found via refresh token) shares the same email and roles then it is the same person sending a request for a new access token so you generate new one for him and send it, otherwise you throw an error with 403 status code
We don't create access token using refresh token, we generate new access token if refresh token is still not expired that's why refresh token is there.
Hi, I need some help with the following question: ### Refresh Case When I refresh the page, my access token is lost, resulting in `undefined` being passed as the access token in requests. You've mentioned that the backend will check the validity of the refresh token, generate a new access token, and retry the request. However, how does the backend identify which user's refresh token to validate in this case? Consider this scenario: - **User 1:** Refreshes the page and sends the next request with an undefined access token. How will the backend identify this user? - **User 2:** Also refreshes the page and sends the next request with an undefined access token. How will the backend distinguish between User 1 and User 2? How does the backend differentiate between the two users and validate the correct refresh token?
after your user is logged in, the user is given an access token. The token is either stored in a secure cookie or localstorage. each future request for more content would pass that access token back to backend. cookies are easy because they are automatically sent with the request, but if its in local storage the app would have to pass it in the requests manually
ok so i just saw this is not the pattern this video is using. Sorry about that. When validating the refresh token, the refresh token is binded to an access token in some way. Either the refresh token is saved alongside the access token onto the users table in DB, or I imagine the refresh token could possibly carry the user id in the JWT. Not sure if he specified that in this video.
user 1 and user 2 have different refreshtokens and this refreshtoken is stored in an http-only cookie, which is accessible to the backend via the request's cookies.
Is this code available into your React Project you are providing? Where could I get this full code in order to study it? Should I create "AuthProvider" file and "Helpers" file as it is displayed in your video for getting the expected result when logging in to our web develpment page? Your reply would be very appreciated. Thansk a lot.
This is wonderful I've always thought that there has got to be a better way to handle authentication than storing it in local storage Thanks for the enlightenment Also would it be possible to share a repo of this code 🙏🏼
good video like always, BUT why in the hell I need this access token? Why refresh token isn't enough? Really I see no reason for that, especially that refresh token is also send with every request.
Yes in that example it’s redundant. I guess you would only need it when you pass any user information on the client in that token. For example current UserId
you need to know if the user is logged in without having to fetch it constantly. For like displaying a manage account button, sign out, etc. or even for sending it with the request on button click
@@PiotrMarkiewicz i believe this method is called an asynchronous token. the key point is to make accesstoken maxage as little as possible and refreshtoken maxage long enough for the user to login to our app. the only reason i guess is security purpose.
I've been putting interceptors in a separate axiosPrivate file that would define an axios instance that I'd use across my application. I'm curious why you put interceptors inside of React. Would placing interceptor outside of react behave any differently?
Saving an auth token in a state (in memory) does not make any difference. We will also have to send it manually with every network call. We can save it as an HTTP-only cookie, so JavaScript access will be restricted, and it will be automatically included in all network calls (e.g., using fetch with credentials: 'include' or with the withCredentials option in Axios). If someone is able to steal our HTTP-only cookies, they have access the body of our network requests anyway.
I think I missed something. Why not also put the access token in the http-only. And instead of using token for the state you use user for the state. If there is an refresh or state loss. User is undefined/ null and the server will send down the user on valid refresh/access token. Edit: Is it for security so the access token is not being send on every request? But if that's true, isn't the refresh token being send on every request being their are both in HTTP-only? Can someone enlightend me?
Because in the access token we will have user information like email, name, profile image, role, etc. So we will decode the access token in the client and use the user info.
First of all thanks you so much of this comprehensive explanation of this croioal part. can you give us an exmple of how doing this redux-toolkit query
I was on project I had to handle authentication.. you can use the react way or just use the next middleware ..next have params functionality and use global state to pass the authentication details tell middleware what route you want to authenticate.. make functions with your logic what sorta role you want to authorise.. then it will be way simpler than react .
If you're using this approach (which I don't necessarily have a problem with), pray to God that whoever is doing the backend knows how to manage http-only refresh cookies, CORS etc. otherwise you'll get blamed for users getting logged out all the time with no means of fixing this yourself.
if we are doing multistep form, while filling the form how to save those data, what is the best practice in industry, if user redirect back to the form how to keep data persistence
suppose you have 3 steps , in this case i will create a parent component that contains 3 childrens components (the 3 steps) i will declare each step's state in the parent component and pass the setter to the child and for rendering the steps just use conditional rendering (using a counter or something ) i hope this help you
how would this cater to multiple components failing at the same time? wouldn't you need a queue of some description with the first to error being responsible for the refresh then release the queue when the refresh is done? otherwise you risk a cascade of refresh requests for 'n' components on the page (think dashboard)
Hi, first of all, nice tutorial, thank you for sharing your knowledge just one question, should user put the credentials again if the 15 min expires right? example: "the user was using a computer from classroom, he forgot his app tab and someone access the computer and refreshed the page and 30 days refresh token was valid, now another person has access without credentials right?", I was using refresh tokens to check if the token was between 10 to 15 minutes and refresh the token. May I'm wrong but I think, if you have a app which have no several security problems we could increased the access token time to 1 day for example. Thank you
that's why you don't keep yourself logged in on public computers! Usually there's a checkbox that says "remember me" or "trust this computer" that enables the refresh token or not. If it's set to false, every 15min you need to re-type credentials
@@cosdensolutions of course, users always do this kind of things and its our fault haha, but yes, and we can make more layers of security if our app has some personal/wealth content. Thank you
One thing that dont make sense to me, if I want to keep the user logged in between refreshes and the access token is kept in memory, how the backend would know which refresh token to check if its valid? I assume that in this case you keep the user id or email in localStorage or some sort, if so, all this trip to secure the authentication it's throw in the trash can.
I have the same question! Everywhere I look I see the same explanation but not a direct answer! If it’s in memory it should mean that refreshing the page will lead to losing the access token lol how are we supposed to keep the user logged in??? 😢
@@MarlonEnglemam Honestly, I was noticing the same thing. Of course memory will be 'safer' but I don't believe he designed this video with user-experience in mind. From my experience, saving a token to an HTTP-only cookie is safe as well. If you are worried about a token being 'leaked' then I would consider using another method of authentication/authorization simply because in order to save the token to memory, the token would have to be readable and therefore sent from the server which makes it just as prone to being leaked as if you save it in an HTTP-only cookie.
why will we refresh the page ? simply when token is expired that will be notify to react app from server than instantly we hit refresh token api sending our expired token as payload , then in refresh token api : we will check that token received from payload is expired (firstly) than we will also check the data in it (email, id) in database or match with refresh token (it will be same ) if it matches then we will simply generate the new token for the user whom we got the payload (email, id etc..) and then send to react app , in react app it will again set state.
@@baasirashraf8291 When you even switch tabs away from a React app and then come back later, it will still refresh itself so the 'refreshes' will happen a lot more often than one would think. What you are explaining is the typical auth workflow where the token is stored in a persisted way (cookies, localstorage etc.). What the author is explaining is to store the token in memory (which is not persisted through any form of refresh whatsoever - think of useState and trying to toggle it to a different state and then refresh to see it go back to its default state). When a token is stored in memory, it is deleted as soon as the app refreshes and with the token being deleted you have no way of 'sending' any credentials whatsoever to even 'refresh' your session. Yes this is more secure as it is harder to locate the token but it is also a bad user experience. Its not a knock on the author but it really should be clarified that sessions in this design will not persist. Memory is very secure but there is a reason a LOT of apps opt for HTTP-only cookies over memory.
If the token is null, do you not already know the call to refreshToken will fail? If it was undefined because of a refresh then the useEffect would hit /api/me to get it, but null only tells you that the user is logged out
is storing the token in local storage or session storage that bad? i mean i can get the tokens from anywhere even though its in memory every api call will have this data, the attacker can easily add a js interceptor and get this header, so just keeping it in memory doesn't actually solve the issue, and also once the page is refreshed and we are passing undefined for token to the server how is it able to validate the http only cookie, how does it identify if its the same user, can you give some clarity on it?
No, and if you want to presist login even when dom tree wont exists (closing browser etc) you must use cookies or local storage. I suggest using cookies.
Why not local storage? - if someone can login to your local machine to extract the JWT then you have bigger problems. Because the JWT is encoded, if its manipulated then the server will reject it.
@@markbarton There's a security concern where, if you use any external scripts, someone could compromise one of those and load malicious code onto your website that first just sends all local storage to an external source before loading the actual script. I think this could also be done with something like a browser extension, but I'm not sure about that. Since I don't think JWTs can be revoked, that's a big problem.
@@ptolemyhenson6838 Ok thats good to know - not using external scripts is good practice anyway but its good to understand the attack vectors and would make sense why you would use http cookies - thanks
@@ptolemyhenson6838 the reason why refresh token is supposed to be stored in database is for revocation use. JWT token is supposed to be stateless, stateless means you don't have to store userinfo or something in the backend to verify it later with those stored infos. When you store jwt tokens in the backend it is not stateless anymore.
I was about to comment the same concern. When user refreshes the Application, the token state becomes undefined. In that case how will the server know if its a valid user without the token or credentials ?
@@SaifullahZubair I found the answer. Refresh token should be stored as "http only". This is the common approach afaik and you can access the token on the server securely without losing it on refresh.
@@SaifullahZubair I found the solution. The refresh token should be stored as 'http only'. With this common way, the server can access the token securely.
But it doesn't really makes sense to me to implement a refresh token? Can't we just send a long lived access token in a http only cookie? Is this approach appropriate?
There are a few considerations here. If you only sent a really long lived access token: - You cannot put the token in the Auth header, because you are not able to access httpOnly cookies from the React app. - If someone stoles your token he is going to be able to access to your account for (whatever lifetime the token has). About the second point, you can think, well, but the refresh token could also be stolen. Thats right, but you are only sending the token in the cookies of /refreshToken request, so less chances. And you can keep a table of "active refresh tokens" for checking if the refresh token has already been used to avoid risks. At the end of the day, you can secure as much as you want the auth system, but I think for most applications this approach (accestoken /refreshToken/ active refreshTokens table) has a good security-performance ratio. At least is what I use in my apps
Is it better to use redux to hold the token in global state, or is there some benefit to using context? (Assuming we already have redux setup in the application)
What happens, in this case, if you refresh the page? I may have missed something but it was not clear to me how to handle that scenario since we're keeping the token only in memory. How should I go about that? I cant just force the user to log back in every time they refresh the page. This is where videos like this always seem to fail to explain... :(
okay so here is a question, user refreshes the window and we are sending undifined as the access token , how does the backend know which refresh token to look at? im confused here. when we hit an api we send an access token which is the only way to authenticate the user, but if we are sending undefined then how is there backend checking which refresh token to this user with undifened as access token? Can anyone please explain?
about the HTTP cookie. there is an extension in chrome. that could export cookies. "Export cookie to pupppeteer" I use it to download my linkedin cookie so i dont have to login... Are they diferrent cookies?
Hey Cosden, Since my Backend has Refresh Token Rotation Strategy, for each time new access_token is generated, new refresh_token is created I got problem when storing, access_token in memory, if user open new multiple tabs, each tab store different access_token, means only one is valid If i made post request on the tab with the access_token which is not expired, but revoked, react call the refresh route and made success to the post request. Is this the way of doing, or I'm doing it wrong ?
Just got some clarification after reading about http-only cookie and answer to my question - "An HTTP-only cookie is a type of cookie that is inaccessible to JavaScript running in the browser" so need to correct some part in the video I think. Refresh token also goes to client side. 🤔
I don't get it , when you say store token in memory, more secure, if you call request API, to api. the token is can see by user/developer right ? so useless, store in memory.
Why store the access token in memory if it will reset every time the page refreshes? A cookie will preserve the session, and since it is HTTP-only, client scripts cannot access it, maintaining the same level of security.
Every tutorial I've seen, doesn't work for me, en context api doesn't update the data of the user instantly, and it is a headache that every time I want to consult the user's information is null, or lose the information when reloading the page, can someone help me?
Thank you very much for the video! I have a question, if anyone can answer I'd be very grateful! So this this kind of authorisation implemented in the backend, how should it work in the following example: I have an app where to display the UI correctly I have to make an api call to the backend and fetch some data. This data then used for the UI rendering and it can be visible to any website user, including just unreguistered visitors. They should be able to see the data, but not change it. In this case, how should I make an api call, if there isn't any users (uless you count frontend as a user), but the backend is protected like in the video? Obviously I can't include login/password into an api call for safety reasons, but I also don't have a token to access the data I need. Is this something that backend should care about and provide me a valid token?
Hey, for this case i think you would have to bypass the authorization for those particular API's , typically they will be get only api to give you the info to render it on the UI, and all other backend routes will be going through the authorization so they will be protected.
Is it refresh token that generate access token? I thought initially we have access token, then we use refresh token to revalidate the access token? Please help
when successfully log in you initially get access and refresh tokens,access is short lived and refresh one have longer expiration date, and then based on that refresh token new access token is issued after one you have is expired.
im little confuse about mine code , if mine access token is null and i make a call with /api/me to generate new access Token , then will i get new access token , if yes then everyone gonna have this accessToken and use even to generate tokens one more confusion , if i gonna store access token in memory then i dont thinks its permanently stores on state , when ever server start stops its gonna clear , even if its store will it gonna be different for all user or accessing same refresh token every user using this web app i'm new to it , im so confuse , please help me
What if the access Token is still valid but the user tries to access a resource he doesn't have access to, leading to a 403 Unauthorized? Wouldn't that result in endless retries?
Hi, can you please share this code just to see and understand more precisely. And what about the csrf random token fit in this architecture?? Can you please create a full fledged authentication and authorisation video please. Thanks
Hope you enjoyed the video! 😁 I also have a really cool and unique course that will teach you way more than this video. You'll learn how to build an actual complex project with React. It's called "Project React" and you can find it at cosden.solutions/project-react. Also, I have a free weekly newsletter called "Import React" with tutorials, news, and cool stuff about React! You can sign up at cosden.solutions/newsletter?s=ytc
Source code?
You are good n unique as online instructor. Most ppl don't explain the road ahead as you do. They just jump to launching IDEs.
The HTTPOnly cookies travel back and forth with every HTTP request and response, just like regular cookies. The only difference is that the browser will not allow the client-side Javascript to access them, which can prevent certain types of attacks.
Correct. That was confusing and then I read about http-only cookie.
Ya, he should have put it beside the client in the graph... not the server.. even though both know it.
yep, he should have mentioned that
Instant subscription, clear, on-point, full of useful theory and practical example. 👏
you make this topic way easy to understand, great work
Great video! The implementation looks really interesting. Could you please share the source code for this project? It would be very helpful for those of us trying to learn and follow along. Thanks!
this one just awesome , please more video about authentication and authorization + a comprehensive one for axios
thanks a lot
one of the few channels worth subscribing...
“Refresh token is only on the server” this is nonsense. Http only cookies are not on servers, cookies are for clients. The server checks the cookie that is sent with every request to the server. It’s not living on the server.
Your video quality is great, but this is a fundamental mistake
Token generate server site jwt through and then send to the client
What about refresh tokens rotation?
@@matis9783 what is the question?
confused as well
Agreed, the refresh token gets sent to the client to be stored as a HTTP-only cookie by the browser and sent on each request (or at least on each request to the path specified by the cookie)
Hello,
If we are sending the token in authorization header, then they will be visible to everyone anyways. Why should we not store the access token in session/localStorage?
Local storage/ session storage /cookies what is the industries recommended ways to store user details and how to use 3 of the ways in react app
Very practical demonstration of the concept! Thanks !
Great tutorial, but I have one question what if the user refreshes the app before the expiration time if so the token in memory will be undefined so how the server will identify the user in the refresh token call ? as the API request token is undefined even if the user has a valid refresh token?
[11:12]
This was actually very helpful and cleared a lot of ambiguity I had. Thank you very much.
Even if an attacker gains access to access token, they can’t do much with it because they don’t know the secret used to sign the JWT. The secret is stored server-side and remains hidden, preventing them from forging or tampering with the token
I understand the concept of saving the access token in memory and why it's more secure to keep it there. However, what I don't understand is how the server knows it's "you" who sent the request for a new access token when the app is refreshed. Is it determined by IP address? By browser? What information is sent from the front end to the backend to verify that the user is the correct one for that refresh token to generate a new access token?
I need to tell the backend developers what they need to implement for the front end to have a correct flow of the tokens. I would greatly appreciate an explanation of this, as I am struggling to understand how to keep the access token in memory. Currently, I have been saving it in session storage.
Exactly my question. If not storing something to identify the user by, how does the server know it's the same user to use the refresh token for?
Ah, http-only cookies are actually stored locally with a set Cookie. The only thing is that they are not accessible through scripts but on subsequent http requests
I handle it this way. You see, if you're using jwt, you encode user data (e.g: email, roles) to it by passing it as a jwt payload when generating a new token. Same thing with refresh token. The only thing is you store refresh token in database in your user entity before setting it in request cookies. Then when handling the refresh route, you extract refresh token from the cookies and first find a user in the database who has the same refresh token, then you decode it, which will allow you to extract encrypted data(as I said before: email, roles). If the user from the database (one you found via refresh token) shares the same email and roles then it is the same person sending a request for a new access token so you generate new one for him and send it, otherwise you throw an error with 403 status code
I think this is what’s missing in the video. I'm not a backend developer, and I noticed there was no code to save the HTTP-only cookie, so I was left wondering, "What magic is happening here?" I did some further research and I think I understand it now. However, a detailed backend explanation would be very useful so we know exactly what's going on.
In the process described, two tokens are created: a refresh token and an access token. The refresh token is sent in an HTTP-only cookie as a header, while the access token is included in the response of the request. The browser automatically saves the cookie when the backend sends it as an HTTP-only cookie, provided that CORS (Cross-Origin Resource Sharing) is properly configured on both the frontend and backend (with credentials allowed). This ensures the cookie is saved and shared with every request. Therefore, if we don't have an access token when a refresh is needed, the refresh token, which exists as a cookie in the browser, will be sent to obtain a new access token.
Maybe it was just me who didn’t fully grasp the concept initially and it was obvious from the start, but asking the question and getting answers helped point me in the right direction. Initially I though the HTTP-only cookie existed only in the server which lead me to misunderstandings.
@@HeinerAngarita Hi, if you need a detailed backend code for handling user authentication and authorization, I can provide you with a link to my github repo. I used express js with typescript, prisma, and postgres for the db. And, if you need one for non-relational db such as MongoDb, I have a second repo for that as well. They're nealy identical in terms of handling the business logic, only difference is the way I query the database
Very nice and concise tutorial.
However, can you answer my question ?.
Should I do authentication myself or use a third party for that ? Also what are the possible vulnerabilities i am exposed to if i do it myself ?
That's great!! Could you upload the source code to your repository?
Thanks for this. I'm voting for this same topic with next js app router please 🙏
If you store token in state won't it get deleted on page refresh? Then what would you send to the server. So every time the page is refreshed the user needs to relogin?
yes when user close window will need to login again
@@mohamedmaher2981 no, on every initial render we send a request to api/me, which checks the refresh token and sends an access token if there is a valid refresh token.
No, refresh token will renew access token so you dont need to relogin, just call renew somewhere in root like base layout
@@tuanvumaihuynh brother tuanvumaihuynh, damn your name is hard... anyhow, can you please elaborate more on how to do that? is there a name for such implementation?
@@ysmr1843 interceptor
Hi Codsen, great video! Thanks for all the wonderful content.
One burning question I've had is why the frontend is responsible for calling the refresh token endpoint? Since the backend is the one sending the 403 with the Unauthorized error, couldn't the backend be responsible for intercepting that request in the error handler and trying to hit the refresh endpoint? Obviously the RT would need to be sent with every request and not just on the specific refresh token endpoint if that were the case, so the AT and RT would be sent with every request.
Any guidance/education on why it's not done all from the backend but rather from the frontend? Is it because now the RT has to be sent with every request? Even with that I would think it's secure because it's still stored in an HTTP-only cookie, but is the concern with a bad actor intercepting the cookie from the request?
Hi, Im no expert but I think it depends. With this approach you are avoiding sending the refresh token in every request, and I think this is important because refresh token being intercepted would be VERY bad for the user. The drawback of this is that every time that you need to refresh the token (you can say around 10 min) the user has to sent 3 requests (1 for trying to do whatever he wants, 1 for refreshing the token when the first request fails and the last one for trying to do again the actual work , this time successfully). I think its a choice between security or reducing that 3 request). In my opinion, those request are not really going to fuck too much your performance and Ive seen that the usual thing to do is as in the video. Hope it helps!
Nice tutorial,
everyone can understand if you create a new video with step-by-step guide from scratch with a demo
Great video. Please make a video on authorisation next .
once again a very great and well-explained video like always !! a BIG THANKS from berlin 🖤
all respect for your whole effort producing those video tutorials!
So hard to find instructors like you.Can you add part two explaining how you would add RBAC in this implementation for role based authentication and have private routes and a hint on how to handle this with nextjs 14.We need to understand fully this phrase "Roll you own auth" and not becoming dependant on thirdy party libraries.Thank you
Where do csrf tokens fit in? How to implement them and how are they different than JWTs?
I need same with app router nextjs. Should I keep refresh logic in client component?
If you find it ,let me know
have you found it?
you should, cause all the logic main point is on the client side
I guess i missed this part, why not store access token in http-only cookie?
Also how do you create a access token using refresh token?
I did that in my application
I handle it this way. You see, if you're using jwt, you encode user data (e.g: email, roles) to it by passing it as a jwt payload when generating a new token. Same thing with refresh token. The only thing is you store refresh token in database in your user entity before setting it in request cookies. Then when handling the refresh route, you extract refresh token from the cookies and first find a user in the database who has the same refresh token, then you decode it, which will allow you to extract encrypted data(as I said before: email, roles). If the user from the database (one you found via refresh token) shares the same email and roles then it is the same person sending a request for a new access token so you generate new one for him and send it, otherwise you throw an error with 403 status code
We don't create access token using refresh token, we generate new access token if refresh token is still not expired that's why refresh token is there.
agree
Amazing video. I always wanted to see something like this. Is there anyway we can get this code so I can read it on my own? Thank you!
Hi,
I need some help with the following question:
### Refresh Case
When I refresh the page, my access token is lost, resulting in `undefined` being passed as the access token in requests. You've mentioned that the backend will check the validity of the refresh token, generate a new access token, and retry the request.
However, how does the backend identify which user's refresh token to validate in this case?
Consider this scenario:
- **User 1:** Refreshes the page and sends the next request with an undefined access token. How will the backend identify this user?
- **User 2:** Also refreshes the page and sends the next request with an undefined access token. How will the backend distinguish between User 1 and User 2?
How does the backend differentiate between the two users and validate the correct refresh token?
after your user is logged in, the user is given an access token. The token is either stored in a secure cookie or localstorage. each future request for more content would pass that access token back to backend. cookies are easy because they are automatically sent with the request, but if its in local storage the app would have to pass it in the requests manually
ok so i just saw this is not the pattern this video is using. Sorry about that. When validating the refresh token, the refresh token is binded to an access token in some way. Either the refresh token is saved alongside the access token onto the users table in DB, or I imagine the refresh token could possibly carry the user id in the JWT. Not sure if he specified that in this video.
user 1 and user 2 have different refreshtokens and this refreshtoken is stored in an http-only cookie, which is accessible to the backend via the request's cookies.
Is this code available into your React Project you are providing? Where could I get this full code in order to study it? Should I create "AuthProvider" file and "Helpers" file as it is displayed in your video for getting the expected result when logging in to our web develpment page? Your reply would be very appreciated. Thansk a lot.
This is wonderful
I've always thought that there has got to be a better way to handle authentication than storing it in local storage
Thanks for the enlightenment
Also would it be possible to share a repo of this code 🙏🏼
good video like always, BUT why in the hell I need this access token? Why refresh token isn't enough? Really I see no reason for that, especially that refresh token is also send with every request.
+
Yes in that example it’s redundant. I guess you would only need it when you pass any user information on the client in that token. For example current UserId
you need to know if the user is logged in without having to fetch it constantly. For like displaying a manage account button, sign out, etc. or even for sending it with the request on button click
@@cosdensolutions ok, this sounds valid, but still I need to fetch every 15 minutes to check token, it will equally work with refresh token
@@PiotrMarkiewicz i believe this method is called an asynchronous token. the key point is to make accesstoken maxage as little as possible and refreshtoken maxage long enough for the user to login to our app. the only reason i guess is security purpose.
bro, you should make a react course man. would be awesome and i hope you consider doing it one day !
Can you please prepare a video on authorization?
I've been putting interceptors in a separate axiosPrivate file that would define an axios instance that I'd use across my application. I'm curious why you put interceptors inside of React. Would placing interceptor outside of react behave any differently?
If you found an answer please let me know
Saving an auth token in a state (in memory) does not make any difference. We will also have to send it manually with every network call.
We can save it as an HTTP-only cookie, so JavaScript access will be restricted, and it will be automatically included in all network calls (e.g., using fetch with credentials: 'include' or with the withCredentials option in Axios).
If someone is able to steal our HTTP-only cookies, they have access the body of our network requests anyway.
You need to know if the user is logged in or not to show according UI my dude, cant do that with a token that's not accessible by js
@@cosdensolutions ohh thats obvious, we can use ping server with same token and save user's data in state on the initial load
I think I missed something. Why not also put the access token in the http-only. And instead of using token for the state you use user for the state. If there is an refresh or state loss. User is undefined/ null and the server will send down the user on valid refresh/access token.
Edit: Is it for security so the access token is not being send on every request? But if that's true, isn't the refresh token being send on every request being their are both in HTTP-only? Can someone enlightend me?
Because in the access token we will have user information like email, name, profile image, role, etc. So we will decode the access token in the client and use the user info.
Thank you so much for your videos, they are very well made and very helpful! thanks for what you are doing!
First of all thanks you so much of this comprehensive explanation of this croioal part.
can you give us an exmple of how doing this redux-toolkit query
Dang, now please do it with next app router. There is no content available on yt about next authentication with a separate backend.
hi did you find any thing yet ?
I was on project I had to handle authentication.. you can use the react way or just use the next middleware ..next have params functionality and use global state to pass the authentication details
tell middleware what route you want to authenticate.. make functions with your logic what sorta role you want to authorise.. then it will be way simpler than react .
If you're using this approach (which I don't necessarily have a problem with), pray to God that whoever is doing the backend knows how to manage http-only refresh cookies, CORS etc. otherwise you'll get blamed for users getting logged out all the time with no means of fixing this yourself.
if we are doing multistep form, while filling the form how to save those data, what is the best practice in industry, if user redirect back to the form how to keep data persistence
suppose you have 3 steps , in this case i will create a parent component that contains 3 childrens components (the 3 steps) i will declare each step's state in the parent component and pass the setter to the child and for rendering the steps just use conditional rendering (using a counter or something ) i hope this help you
Very good video.Keep doing videos like this.Thanks a lot!
Awesome videos, thank you. Can you please post a video on user Authentication in React using RTK query
JWTs are not encrypted but encoded. You can encrypted though in case you want to ensure confidentiality
how would this cater to multiple components failing at the same time? wouldn't you need a queue of some description with the first to error being responsible for the refresh then release the queue when the refresh is done? otherwise you risk a cascade of refresh requests for 'n' components on the page (think dashboard)
any solution to this?
Hi, first of all, nice tutorial, thank you for sharing your knowledge just one question, should user put the credentials again if the 15 min expires right? example: "the user was using a computer from classroom, he forgot his app tab and someone access the computer and refreshed the page and 30 days refresh token was valid, now another person has access without credentials right?",
I was using refresh tokens to check if the token was between 10 to 15 minutes and refresh the token. May I'm wrong but I think, if you have a app which have no several security problems we could increased the access token time to 1 day for example.
Thank you
that's why you don't keep yourself logged in on public computers! Usually there's a checkbox that says "remember me" or "trust this computer" that enables the refresh token or not. If it's set to false, every 15min you need to re-type credentials
@@cosdensolutions of course, users always do this kind of things and its our fault haha, but yes, and we can make more layers of security if our app has some personal/wealth content. Thank you
One thing that dont make sense to me, if I want to keep the user logged in between refreshes and the access token is kept in memory, how the backend would know which refresh token to check if its valid? I assume that in this case you keep the user id or email in localStorage or some sort, if so, all this trip to secure the authentication it's throw in the trash can.
I have the same question! Everywhere I look I see the same explanation but not a direct answer! If it’s in memory it should mean that refreshing the page will lead to losing the access token lol how are we supposed to keep the user logged in??? 😢
@@MarlonEnglemam Honestly, I was noticing the same thing. Of course memory will be 'safer' but I don't believe he designed this video with user-experience in mind. From my experience, saving a token to an HTTP-only cookie is safe as well. If you are worried about a token being 'leaked' then I would consider using another method of authentication/authorization simply because in order to save the token to memory, the token would have to be readable and therefore sent from the server which makes it just as prone to being leaked as if you save it in an HTTP-only cookie.
why will we refresh the page ? simply when token is expired that will be notify to react app from server than instantly we hit refresh token api sending our expired token as payload , then in refresh token api : we will check that token received from payload is expired (firstly) than we will also check the data in it (email, id) in database or match with refresh token (it will be same ) if it matches then we will simply generate the new token for the user whom we got the payload (email, id etc..) and then send to react app , in react app it will again set state.
@@baasirashraf8291 When you even switch tabs away from a React app and then come back later, it will still refresh itself so the 'refreshes' will happen a lot more often than one would think.
What you are explaining is the typical auth workflow where the token is stored in a persisted way (cookies, localstorage etc.). What the author is explaining is to store the token in memory (which is not persisted through any form of refresh whatsoever - think of useState and trying to toggle it to a different state and then refresh to see it go back to its default state). When a token is stored in memory, it is deleted as soon as the app refreshes and with the token being deleted you have no way of 'sending' any credentials whatsoever to even 'refresh' your session. Yes this is more secure as it is harder to locate the token but it is also a bad user experience.
Its not a knock on the author but it really should be clarified that sessions in this design will not persist. Memory is very secure but there is a reason a LOT of apps opt for HTTP-only cookies over memory.
If the token is null, do you not already know the call to refreshToken will fail? If it was undefined because of a refresh then the useEffect would hit /api/me to get it, but null only tells you that the user is logged out
is storing the token in local storage or session storage that bad? i mean i can get the tokens from anywhere even though its in memory every api call will have this data, the attacker can easily add a js interceptor and get this header, so just keeping it in memory doesn't actually solve the issue, and also once the page is refreshed and we are passing undefined for token to the server how is it able to validate the http only cookie, how does it identify if its the same user, can you give some clarity on it?
Exactly!
yes, google cross-site scripting
Does this cover the secure storage of JWTs? Right now I'm just using local storage, but obviously that isn't good enough for production.
No, and if you want to presist login even when dom tree wont exists (closing browser etc) you must use cookies or local storage. I suggest using cookies.
Why not local storage? - if someone can login to your local machine to extract the JWT then you have bigger problems. Because the JWT is encoded, if its manipulated then the server will reject it.
@@markbarton There's a security concern where, if you use any external scripts, someone could compromise one of those and load malicious code onto your website that first just sends all local storage to an external source before loading the actual script. I think this could also be done with something like a browser extension, but I'm not sure about that.
Since I don't think JWTs can be revoked, that's a big problem.
@@ptolemyhenson6838 Ok thats good to know - not using external scripts is good practice anyway but its good to understand the attack vectors and would make sense why you would use http cookies - thanks
@@ptolemyhenson6838 the reason why refresh token is supposed to be stored in database is for revocation use. JWT token is supposed to be stateless, stateless means you don't have to store userinfo or something in the backend to verify it later with those stored infos. When you store jwt tokens in the backend it is not stateless anymore.
In case there is no access token, how the server can know the refresh token belongs to the user? We don't store the refresh token in client.
I was about to comment the same concern.
When user refreshes the Application, the token state becomes undefined. In that case how will the server know if its a valid user without the token or credentials ?
@@SaifullahZubair I found the answer. Refresh token should be stored as "http only". This is the common approach afaik and you can access the token on the server securely without losing it on refresh.
@@SaifullahZubair I found the solution. The refresh token should be stored as 'http only'. With this common way, the server can access the token securely.
But it doesn't really makes sense to me to implement a refresh token? Can't we just send a long lived access token in a http only cookie? Is this approach appropriate?
There are a few considerations here. If you only sent a really long lived access token:
- You cannot put the token in the Auth header, because you are not able to access httpOnly cookies from the React app.
- If someone stoles your token he is going to be able to access to your account for (whatever lifetime the token has).
About the second point, you can think, well, but the refresh token could also be stolen. Thats right, but you are only sending the token in the cookies of /refreshToken request, so less chances. And you can keep a table of "active refresh tokens" for checking if the refresh token has already been used to avoid risks. At the end of the day, you can secure as much as you want the auth system, but I think for most applications this approach (accestoken /refreshToken/ active refreshTokens table) has a good security-performance ratio. At least is what I use in my apps
I am wondering your decision about choosing HTTP code 403 over 401, which is the actual standard for Unauthorized.
Same question
WOW, amazing! Thank you so much!
if refresh token is enough for authenticate why i must use access token?
same question here
Is it better to use redux to hold the token in global state, or is there some benefit to using context? (Assuming we already have redux setup in the application)
redux is fine!
What happens, in this case, if you refresh the page? I may have missed something but it was not clear to me how to handle that scenario since we're keeping the token only in memory. How should I go about that? I cant just force the user to log back in every time they refresh the page. This is where videos like this always seem to fail to explain... :(
that's what comes to my mind too, on page refresh the states or variable will be gone
Unless you keep sending refresh token request to backend before state is destroyed
@@deekandau4596 what dom EVENT to use to do that?
okay so here is a question, user refreshes the window and we are sending undifined as the access token , how does the backend know which refresh token to look at? im confused here. when we hit an api we send an access token which is the only way to authenticate the user, but if we are sending undefined then how is there backend checking which refresh token to this user with undifened as access token? Can anyone please explain?
@shubhamchandel-gs4so Same question
refresh token not only reside on the server but sent to the client. The refresh token always send along every request to the server.
when you store token in in-memory (state or variable) it will be gone when you refresh right?
Yes
@@Priva_C so it isn't feasible to store and retrieve token in memory as refreshing the page will reset the state/variable
Thank you so much for this video. Could you kindly share the code for this, it makes it even more easier to follow along.
can you please make a video on the auth flow with tanstack query
about the HTTP cookie.
there is an extension in chrome. that could export cookies. "Export cookie to pupppeteer"
I use it to download my linkedin cookie so i dont have to login...
Are they diferrent cookies?
Hey Cosden,
Since my Backend has Refresh Token Rotation Strategy, for each time new access_token is generated, new refresh_token is created
I got problem when storing, access_token in memory, if user open new multiple tabs, each tab store different access_token, means only one is valid
If i made post request on the tab with the access_token which is not expired, but revoked, react call the refresh route and made success to the post request.
Is this the way of doing, or I'm doing it wrong ?
What font do you use in your thumbnail?
Can you do next auth session for us?☺
in documentation we can see: "Dont use useLayoutEffect if its not important" .... why u are using ? whats other ways ??? 🤔🤔🤔🤔
@Cosden Solutions
sir is it will be persistent
what happen when the user will refresh the page so it will again to login?
No, it is just gonna load and get the access token and start using it normally, user won't notice anything
@@hazemkhaled9416 As much its "secure" don't we have any other more convenient way?
@@hazemkhaled9416 what I thought.
Hy it's looks awesome..and code setup is also excellent can you share the repo link of code.
Great video!! Is it possible to share whole atuh provider code with us?
@Cosden Solutions
please provide the code link
Don't ask. He's trying to charge for that source code snippet now
Where you store the access token for persistency?
You don't. The backend stores the refresh token in a http-only cookie for 30 days. That lives on the browser but is inaccessible by JS
awesome video tutorial!
very helpful. thanks
can you please make a video where you create the server and implement it in the react app
I'm having trouble with authentication and authorization
Hi, what if I had a different domain for backend?
So what's the point of 15 minutes expiration time with Access token? If we are getting new one anyway by validating Refresh token on server?
Just got some clarification after reading about http-only cookie and answer to my question - "An HTTP-only cookie is a type of cookie that is inaccessible to JavaScript running in the browser" so need to correct some part in the video I think. Refresh token also goes to client side. 🤔
What happens when the user refreshes the browser wouldn't the token be removed from the memory? How do you handle that use case
Indeed, if user refreshes page they will be unauthorized
so i want to send my token back to server to check if it is still valid or not?
I don't get it , when you say store token in memory, more secure,
if you call request API, to api. the token is can see by user/developer right ? so useless, store in memory.
yes, i am confused as well
does anyone know where can i get the whole code!?
I want that too!
Thanks! very useful, could you please share the backend refreshtoken source code? 🙌🏻
Goodluck on nba finals luka!
What is API variable, is there a github repo for this.
Why store the access token in memory if it will reset every time the page refreshes? A cookie will preserve the session, and since it is HTTP-only, client scripts cannot access it, maintaining the same level of security.
you need to know if the user is signed in or not in the UI. can't do that with the http-only cookie
Every tutorial I've seen, doesn't work for me, en context api doesn't update the data of the user instantly, and it is a headache that every time I want to consult the user's information is null, or lose the information when reloading the page, can someone help me?
next 14 server auth please!! so good this one
This is huge, thank you a lot
Thank you very much for the video! I have a question, if anyone can answer I'd be very grateful! So this this kind of authorisation implemented in the backend, how should it work in the following example: I have an app where to display the UI correctly I have to make an api call to the backend and fetch some data. This data then used for the UI rendering and it can be visible to any website user, including just unreguistered visitors. They should be able to see the data, but not change it. In this case, how should I make an api call, if there isn't any users (uless you count frontend as a user), but the backend is protected like in the video? Obviously I can't include login/password into an api call for safety reasons, but I also don't have a token to access the data I need. Is this something that backend should care about and provide me a valid token?
Hey, for this case i think you would have to bypass the authorization for those particular API's , typically they will be get only api to give you the info to render it on the UI, and all other backend routes will be going through the authorization so they will be protected.
@@naveenjain417 thank you for the reply! we came to the same conclusion with my backend colleague!
Please make a full tutorial on this topic with real world application
That's project React 😁
@@cosdensolutions yes, real world React projects with jwt access and refresh tokens please thank you
I don't understand what happens if the user refresh the browser's page ?
the backend will return a new access token to use for 15 mins or next refresh, whichever comes first!
Is it refresh token that generate access token? I thought initially we have access token, then we use refresh token to revalidate the access token? Please help
when successfully log in you initially get access and refresh tokens,access is short lived and refresh one have longer expiration date, and then based on that refresh token new access token is issued after one you have is expired.
Fail on multiples requests if you are on login page for example.
Cause loops if you are not authenticated
Please Make React Projects I Think You Can Make Mind-blowing projects
very good sir
im little confuse about mine code , if mine access token is null and i make a call with /api/me to generate new access Token , then will i get new access token ,
if yes then everyone gonna have this accessToken and use even to generate tokens
one more confusion , if i gonna store access token in memory then i dont thinks its permanently stores on state , when ever server start stops its gonna clear , even if its store will it gonna be different for all user or accessing same refresh token every user using this web app
i'm new to it , im so confuse , please help me
What if the access Token is still valid but the user tries to access a resource he doesn't have access to, leading to a 403 Unauthorized? Wouldn't that result in endless retries?
+
Hi, can you please share this code just to see and understand more precisely. And what about the csrf random token fit in this architecture?? Can you please create a full fledged authentication and authorisation video please. Thanks
where can i access your code?
i was waiting for this video