I know everyone is hyping that don’t store tokens in local or session storage. But the reality is if your application is vulnerable to XSS attacks then an attacker can high jacks your tokens stored even in http only cookie by triggering an fetch request to his malicious domain with credentials set to true. So I personally think that we should give more focus on preventing any sort of XSS vulnerabilities in our site rather than deciding where we store our tokens. Personally I prefer session storage as it expires when user closes browser tab. Also please note that I am not saying that author is completely wrong. This is a good quality video. Just saying that this approach will also fails if we have XSS vulnerability.
This was/is a phenomenal video. Though not titled microservices, this is the only video that I've found that helped me with the front end side of handling APIs. Thank you for making this.
Hello Franz, very nice video!! Great content too! However, you left out something. The cookie holding the refresh token is still susceptible to CSRF attacks. And once that happens, it’s game over. HttpOnly alone won’t save the cookie from CSRF attacks. You need additional settings on the refresh-token cookie 🍪 for GraphQL. Namely: Path: /graphql; Domain: localhost:4500; SameSite: Strict. Now, with these additional settings, the refresh-token cookie is not vulnerable to CSRF via abuse of ambient authority on cross-site, cross-domain scenarios
Hi Ifeora, i want ask different question , why i need refresh token? i mean if the security comes from the cookie flags((flags: HttpOnly + Secure + SameSite )) , so why i even need to refresh token ? why not to simply store the access token in the secure cookie flags (flags: HttpOnly + Secure + SameSite )
Wow, this is the probably the best discussion of how to securely store user credentials in the browser. I thought this approach made sense, but everyone seems to use local storage or cookies so I let it go. You just confirmed my intuition, and more! Thanks Kati, you’re awesome🙌🏽😎☝🏽. Ofc Im subbed 😁🎊
Great Video. Thanks alot. I gave a question. Why not just store the JWT token inside the HTTP only cookie since XSS attacks can't get to it. Instead of the hassle of using a refresh token. Thank you.
Problem with this method is, if someone gets the refresh token, they may infinitely keep on getting new tokens. One would say, to tackle this issue, keep the expiry time of small duration. However, it’ll create another issue. Suppose, if I shut down my system and come back the next day, the refresh token would have expired by now. Therefore, I’ll have to log in again. What could be the potential solution to such problems?
What’s the point of having a regular JWT if we have the refresh-token which is used to figure out if the session is active and is secure enough to not change it every time?
It's not just easy revocation. The refresh token should only be sent via a cookie when refreshing the regular JWT using include credentials. This prevents CSRF attacks. We use the JWT for all other API calls.
Important thing to highlight that such an approach is great for web browser applications but not a good idea to follow it if we are creating same Auth API for IOS or Android as they don't have the cookies mechanism.
For browser-based applications: When the user logs in or authenticates, your server can generate a JWT token and set it as a cookie in the HTTP response. The cookie should have the HttpOnly flag set to prevent client-side JavaScript access for enhanced security. The browser will automatically include this cookie in subsequent requests to your API. For native mobile applications: In the case of native mobile applications, cookies are typically not managed by the application directly. Instead, you can handle the token management manually by extracting the JWT token from the server's response and storing it securely within the mobile application. You have several options for storing the token securely, such as using the Keychain (iOS) or Keystore (Android) mechanisms mentioned earlier.
Thank you so much for this tutorial. I have a question. What happens when the time taken to get the authentication response backend is longer? Don't you think depending on the server for authentication is expensive in terms of time?
Thank you @kati, this is a great tutorial. However, it still seems dependent on having the backend team agree to use refresh tokens. Or do you think there might be any other feasible approach ?
Haha, no. backend must agree to send refresh tokens just like they agreed to send access tokens in the first place. Planning to do another tutorial showing backend peeps how to generate access tokens.
@@vickylance If you want. But my take is that the backend sends the refresh token once in a while maybe 30 - 60 days. if it expires. The frontend handles how they store the refresh token and does not make multiple calls to the backend for the refresh token. If the refresh token expires, you need to authenticate the app again to get the refresh token. The access token can be transferred automatically via cookies.
Great info and thank you for sharing sir, I can see you are setting the new token to the header after the request inorder to persist it. How can you do this with axios, meaning how can you set a header after request with axios or am I missing something.
But doesnvt the refresh token have the same problem as the cookie? Can't an attacker just make a request with the refresh token and get the jwt that way?
Thank you so much. it's really helpful. But what if the user does not log out and after the access token has expired (but not the refresh token)then still the user will be able to access website without even login. So, if the user1 logs in from one device and forgets to logout(and then say device is stolen) then other users can access the other user's account without login(provided user1 doesn't clear cache and cookies)?
I do not understand why people completely stopped talking about CSRF-attacks. Developers actually stopped using httpOnly cookies and went for localStorage for a reason. Cookies, httpOnly or not, are very much prone to an attack. They are not prone to an XSS-attack but they are prone to a CSRF-attack. localStorage are not prone to CSRF though. And if XSS does happen then even with well protected cookies an attacker has huge power and still is able to make a lot of damage.
by storing the refresh token in a httponly cookie, does it prevent an attacker from using it ? my current set up is quite the same ,storing the access token in memory and returning it in a response body from the server and at the same time the server sets up a httponly cookie containing the refresh token...For now i havent found a way to encrypt and sign the token (i am using ktor for the backend) as i use a call.response.cookies.append() method to set my cookie
i have a question. you set the refresh token in http cookie. and in the use effect you're sending it to get a new token. if the refresh token is not accessible via javascript how come you're sending it for a new acces token.
ok the JWTs are not accessible from JS, but what's the matter if the hacker can just look at headers of the request using the developer tools as you did? I'm missing something? what do I need to study to understand?
As for the situation where a hacker is able to look at your headers, then it's probably a MITM (man in the middle) attack, where the hacker is intercepting your request. In that case, first, you have SSL as first layer of protection, they probably still can't see the request details. Secondly, you have the CORS setting on the server to allow only request made from your own site. In the end, nothing is 'un-hackable', but just lots of different good practices to make it more difficult for hackers to breach.
So how would you implement "remember me" functionality? I was thing about store it in sessionstorage when not checked and localstotage when checked. If I use your approach I don't know how to implement it (mainly unchecked)
I don't think so, he just overwrites the refresh_token with no value, so the frontend does not have it. Basically JWT is stateless, the refresh_token cookie cleared technically is valid until its expiry (but our backed has removed it from the browser when we log out). If you blacklist the cookie, it becomes stateful and you are better off doing session management than using JWT then.
Very nice tutorial. I ma tried following this using axios, But my refresh token not work, beacause this trun before login and i dont have a token yet. I need a token to refresh my login. How can fix this. I hope you understand my problem.
Great video. Question for you, Does this work with a net core web API project? I followed your video very carefully and the only thing that works for me is setting the the cookie in the response after I logging. The subsequent request (using fetch: credentials: "include", also server expecting credential) just does not send any cookie in the header. My setup is, backend: localhost:92 and frontend: localhost:80.
This is awesome sir, really appreciate your video, but i getting an error if i access login page with no refresh_token in cookies, because the page that do network call "refreshtoken" when the page reload. how to handle this?
@@KatiFrantzv Please do. Especially laravel+intertia.js (vue.js side I would suggest ;) ) and another exciting part is the "new" blade component/slots techniques.
Kati, great video. I was trying to implement your JWT in-memory technique using Axios but it did not work. I was wondering if you could add another video explaining each component.
Thank you a lot Kati, this video helps a lot dealing with security and best practices. A question, how would you handle the access token in SSR, like in Next.js? I don't know how the Next server can get the access token saved in client memory.
Thanks for the tutorial. However can't a malicious user still make requests (of course to our own end points) and mess things up? (source link below) ua-cam.com/video/M6N7gEZ-IUQ/v-deo.html Eagerly waiting for your input. Thanks again!
The missing part of any JWT courses. Thank you.
I know everyone is hyping that don’t store tokens in local or session storage. But the reality is if your application is vulnerable to XSS attacks then an attacker can high jacks your tokens stored even in http only cookie by triggering an fetch request to his malicious domain with credentials set to true. So I personally think that we should give more focus on preventing any sort of XSS vulnerabilities in our site rather than deciding where we store our tokens. Personally I prefer session storage as it expires when user closes browser tab. Also please note that I am not saying that author is completely wrong. This is a good quality video. Just saying that this approach will also fails if we have XSS vulnerability.
If the cookie is set with the sameSite flag, then the attacker will not be able to trigger a fetch request to his malicious domain.
You could configure CORS for specific domains of your clients.
This was/is a phenomenal video. Though not titled microservices, this is the only video that I've found that helped me with the front end side of handling APIs. Thank you for making this.
Damnn!! this is what every JWT newbie needs to know how to understand the refresh token & its usage in the front end 🔥. Thank you Sir!!!
Hello Franz, very nice video!! Great content too! However, you left out something. The cookie holding the refresh token is still susceptible to CSRF attacks. And once that happens, it’s game over. HttpOnly alone won’t save the cookie from CSRF attacks. You need additional settings on the refresh-token cookie 🍪 for GraphQL. Namely: Path: /graphql; Domain: localhost:4500; SameSite: Strict. Now, with these additional settings, the refresh-token cookie is not vulnerable to CSRF via abuse of ambient authority on cross-site, cross-domain scenarios
Hi Ifeora, i want ask different question , why i need refresh token?
i mean if the security comes from the cookie flags((flags: HttpOnly + Secure + SameSite )) , so why i even need to refresh token ?
why not to simply store the access token in the secure cookie flags (flags: HttpOnly + Secure + SameSite )
Wow, this is the probably the best discussion of how to securely store user credentials in the browser. I thought this approach made sense, but everyone seems to use local storage or cookies so I let it go. You just confirmed my intuition, and more! Thanks Kati, you’re awesome🙌🏽😎☝🏽. Ofc Im subbed 😁🎊
I searched a lot about these refresh token and access token, finally, I understood what's going on. Thank you sir
Thank u so much, interested in starting so soft during quarintine and just need a place to get started, thx for the support
You do a really great job explaining. It flows really well and you cover a lot without getting too much into the weeds.
I support this comment, great explanation and great flow
You went the extra mile. All the rest in UA-cam were lazy or lacking of knowledge or maybe just not as clear as you are. Thanks for your video man!
This is the best I have watch so far on jwt auth.
I've been looking for this!!!! I saw an article by Hasura and I tried it but I can't seem to fully complete it, thank you so much!!
Thanks so much! Every time was missing why the refresh token is even should be used
tysm almost a week I searching about the refresh token huhu finally you saved me tysm!
Damn, this is really good man! So much I've learned here that I need to use in my apps going forward!
Great Video. Thanks alot.
I gave a question. Why not just store the JWT token inside the HTTP only cookie since XSS attacks can't get to it. Instead of the hassle of using a refresh token. Thank you.
Problem with this method is, if someone gets the refresh token, they may infinitely keep on getting new tokens.
One would say, to tackle this issue, keep the expiry time of small duration.
However, it’ll create another issue. Suppose, if I shut down my system and come back the next day, the refresh token would have expired by now. Therefore, I’ll have to log in again.
What could be the potential solution to such problems?
What’s the point of having a regular JWT if we have the refresh-token which is used to figure out if the session is active and is secure enough to not change it every time?
I think has to do mostly with easy token revocation and a finer control
It's not just easy revocation. The refresh token should only be sent via a cookie when refreshing the regular JWT using include credentials. This prevents CSRF attacks. We use the JWT for all other API calls.
also, what if this RT get's leaked? What's the point?
excellent tutorial! explained in a crisp & understandable way. thank you very much. :)
But an attacker could make a request to his own server and then read the refresh token? Or am I thinking wrong
Important thing to highlight that such an approach is great for web browser applications but not a good idea to follow it if we are creating same Auth API for IOS or Android as they don't have the cookies mechanism.
ua-cam.com/video/uXDnS5PcjCA/v-deo.html&ab_channel=LearnWebCode
For browser-based applications: When the user logs in or authenticates, your server can generate a JWT token and set it as a cookie in the HTTP response. The cookie should have the HttpOnly flag set to prevent client-side JavaScript access for enhanced security. The browser will automatically include this cookie in subsequent requests to your API.
For native mobile applications: In the case of native mobile applications, cookies are typically not managed by the application directly. Instead, you can handle the token management manually by extracting the JWT token from the server's response and storing it securely within the mobile application. You have several options for storing the token securely, such as using the Keychain (iOS) or Keystore (Android) mechanisms mentioned earlier.
Thank you soooo much kati ... this was really helpful !!
Thank you so much for this tutorial. I have a question. What happens when the time taken to get the authentication response backend is longer? Don't you think depending on the server for authentication is expensive in terms of time?
It is, but is normal for SSR apps, the approach for an SPA will be different to this, and requires a different authentication pattern.
Thank you @kati, this is a great tutorial. However, it still seems dependent on having the backend team agree to use refresh tokens. Or do you think there might be any other feasible approach ?
Haha, no. backend must agree to send refresh tokens just like they agreed to send access tokens in the first place. Planning to do another tutorial showing backend peeps how to generate access tokens.
@@KatiFrantzv If the backend keeps sending refresh tokens every time, have you considered the overhead that would cause at the backend?
@@bloggrammer use redis?
@@vickylance If you want. But my take is that the backend sends the refresh token once in a while maybe 30 - 60 days. if it expires. The frontend handles how they store the refresh token and does not make multiple calls to the backend for the refresh token.
If the refresh token expires, you need to authenticate the app again to get the refresh token.
The access token can be transferred automatically via cookies.
Great info and thank you for sharing sir, I can see you are setting the new token to the header after the request inorder to persist it. How can you do this with axios, meaning how can you set a header after request with axios or am I missing something.
Thank you for addressing this topic, there is a lot of misinformation out there. :)
Thanks a lot for this, great tutorial, been looking for this for a while
But doesnvt the refresh token have the same problem as the cookie? Can't an attacker just make a request with the refresh token and get the jwt that way?
Thanks for the kind words, I'm always happy to help! Let know if you'd like any videos on specific topics in the future. I wish you all the
Thank you so much. it's really helpful. But what if the user does not log out and after the access token has expired (but not the refresh token)then still the user will be able to access website without even login. So, if the user1 logs in from one device and forgets to logout(and then say device is stolen) then other users can access the other user's account without login(provided user1 doesn't clear cache and cookies)?
I do not understand why people completely stopped talking about CSRF-attacks. Developers actually stopped using httpOnly cookies and went for localStorage for a reason. Cookies, httpOnly or not, are very much prone to an attack. They are not prone to an XSS-attack but they are prone to a CSRF-attack. localStorage are not prone to CSRF though. And if XSS does happen then even with well protected cookies an attacker has huge power and still is able to make a lot of damage.
No expert, but I think the new suggestion is to use sameSite strict or lax.
Oh glad to see you my best teacher i hope to see laravel course soon from you :)
Laravel is coming soon, thanks !
Thanks for sharing this, it's awesome. Gonna try your package very soon.
Thanks, This what I'm Looking for. I'm from your Udemy Course. 🔥
This was such a good watch, thank you!
Thanks! That was exactly what I was looking for!
by storing the refresh token in a httponly cookie, does it prevent an attacker from using it ? my current set up is quite the same ,storing the access token in memory and returning it in a response body from the server and at the same time the server sets up a httponly cookie containing the refresh token...For now i havent found a way to encrypt and sign the token (i am using ktor for the backend) as i use a call.response.cookies.append() method to set my cookie
i have a question. you set the refresh token in http cookie. and in the use effect you're sending it to get a new token. if the refresh token is not accessible via javascript how come you're sending it for a new acces token.
but you are storing refresh token in cookies so it is not in-memory
Why not just store the main access token as a cookie? What's the need for the refresh token?
ok the JWTs are not accessible from JS, but what's the matter if the hacker can just look at headers of the request using the developer tools as you did? I'm missing something? what do I need to study to understand?
As for the situation where a hacker is able to look at your headers, then it's probably a MITM (man in the middle) attack, where the hacker is intercepting your request.
In that case, first, you have SSL as first layer of protection, they probably still can't see the request details. Secondly, you have the CORS setting on the server to allow only request made from your own site.
In the end, nothing is 'un-hackable', but just lots of different good practices to make it more difficult for hackers to breach.
'in this tutorial'
So how would you implement "remember me" functionality? I was thing about store it in sessionstorage when not checked and localstotage when checked. If I use your approach I don't know how to implement it (mainly unchecked)
How would you handle same application in multiple tabs? Or on multiple devices?
Bravo, great explanation, thanks for sharing
This is very helpful! Very well explained. Thanks!
Great video! btw, by clearing it to the backend you mean performing a blacklisting for the refresh and access tokens right?
I don't think so, he just overwrites the refresh_token with no value, so the frontend does not have it.
Basically JWT is stateless, the refresh_token cookie cleared technically is valid until its expiry (but our backed has removed it from the browser when we log out). If you blacklist the cookie, it becomes stateful and you are better off doing session management than using JWT then.
How could a PWA get the user information using this strategy while offline or on a unstable connection?
can any one answer why cookies are getting clear when refresh the page ?
Well can't seem to figure why in the dev tools/network graphQl is falling to load response data
Thank you Katie Frantz. Would love to work with Tensei but seems there's no enough documentation for it yet.
Yes there isn't yet, but please watch the repository so you know when the documentation is done. Thanks !
Cool!
No probs
Very nice tutorial. I ma tried following this using axios, But my refresh token not work, beacause this trun before login and i dont have a token yet. I need a token to refresh my login. How can fix this. I hope you understand my problem.
You are very good, your speak is very clear.. Thanks.
Hi, isn't the refresh token is vulnerable to CSRF attack?
Great video. Question for you, Does this work with a net core web API project? I followed your video very carefully and the only thing that works for me is setting the the cookie in the response after I logging. The subsequent request (using fetch: credentials: "include", also server expecting credential) just does not send any cookie in the header. My setup is, backend: localhost:92 and frontend: localhost:80.
try proxy
awesome tutorial, thank you for sharing
This is awesome sir, really appreciate your video, but i getting an error if i access login page with no refresh_token in cookies, because the page that do network call "refreshtoken" when the page reload. how to handle this?
Glad you're back, wish you would do more tutorials with laravel
Haha, thanks. Watch the space. Might be doing some laravel stuff in future.
@@KatiFrantzv Please do. Especially laravel+intertia.js (vue.js side I would suggest ;) ) and another exciting part is the "new" blade component/slots techniques.
Great video! But why not just store the access token as an httponly cookie? How is that less secure?
Great video! have your like good man !
at 14:30 you said that we shouldn't store our token in local storage nor in cookies. Isn't that what you're doing though?
Kati, great video. I was trying to implement your JWT in-memory technique using Axios but it did not work. I was wondering if you could add another video explaining each component.
hey man did you ever figure this out? would love to see an example if you did.
I'm actually curious did you made this work? I wanna how you did this on Axios
very very good video on any level, thank you so much
Nice...can you do this same tutorial for Vue JS 3?
There’s nothing wrong with storing tokens in local storage. If your site has XSS vulnerabilities, you have much bigger issues.
hi thanks for this tutorial.but i think all users have to login every 1 hour.is it true? is there a good solution for keeping token valid for 1 month?
Amazing!!!!!!!
Thanks alot brother!!!
What is the request function in the client context mean ??
Awesome dude Thank you very much, this is awesome.
Is this going to work when a cluster of requests goes out with expired refresh token, almost at the same moment? There is gonna be a race condition.
Which text extension do you use?
or theme extension
thank you, really easy to understand
Can this be done with express instead of tensei?
great video. anyone got an example of this using axios?
i was able to figure it out. pretty ez.
Thanks so much!
03:44 Backend response
04:06 Not using local storage | Immunity to cross-site scripting attacks
thank god!!!! and thanks to you
i think you didnt mention how long you have been doing it
Muchas gracias, tu explicacion me sirvio para codificar una autenticacion segura utilizando ReactJS + Express + SQLServer :D
¿Puedo ver tu configuración?
Huh, that was very useful. Thank you. You may have just saved my ass :D
Thank you a lot Kati, this video helps a lot dealing with security and best practices. A question, how would you handle the access token in SSR, like in Next.js? I don't know how the Next server can get the access token saved in client memory.
access token just for client side.
Encrypt localStorage values with AES-256.
Let's see how it gets hacked then.
Resources on how to do this please?
thank you for the comprehensive walk thru!
awesome video mate!
Thank you very much !
Jajajajaj damn,you take security pretty seriusly.
Thanks for the course,I'll be using it
What is in that client folder i didn't get it
what u doing
Client is the react , api is most probably node.
Nice but csrf?
This is amazing
You're the best!
Thank you
Thank you so much
Nice.
wait thre's still people using local storage for auth?
oh god
you rock man
Thank you
Awesome Tutorial ++++++++++++++++++++++++++
💯
nailed it shut
Can't really concentrate on the content, that font is too distracting...
Thanks for the tutorial. However can't a malicious user still make requests (of course to our own end points) and mess things up? (source link below)
ua-cam.com/video/M6N7gEZ-IUQ/v-deo.html
Eagerly waiting for your input. Thanks again!