JWT Authentication | Persist Login State on Refresh | MERN Stack

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
the react app in our mirnstack project is receiving an access token and a refresh token with each successful login let's put these jwts to work and learn how to use them to persist our login state after a page refresh too [Music] hello and welcome i'm dave today we will apply jwt access and refresh tokens to our react app request for continuous authorization and we'll also learn how to persist our login state after a page refresh i'll provide links to example source code and all resources in the description below our starter code today is the completed code from lesson9 so we're just going to open the package.json and change this lesson 09 to lesson 10 and we can save the package json and let's move to the user stories now previously we checked off 10 through 13 we've also got number two and number four checked off of our list and really i think we could check off number seven because we provided our log out option in the last lesson but the others were not quite ready to check off yet if we look at some of these were very close like add an employee log into the notes app we really did that in the last lesson but i can't say it's complete until we go ahead and provide those permissions and role-based user access so we're not going to check that off yet kind of the same for eight and nine where we have require users to log in at least once per week we'll eventually set that refresh token to a 7-day expiration but we're not quite finished with that yet also provide a way to remove employee access as soon as possible if needed we had put in an active status for each employee that can be checked or unchecked and we'll go ahead and check that off when we also put in the permissions so only an admin or manager can check that or uncheck it so we're very close on some of these and i think a lot of these will fall into place after we get those permissions in place we'll go ahead and save our user stories for now and let's move on to our source directory and in the source directory we need to open up the app directory and then the api directory and then the api slice dot js so far this isn't too complicated and we've been injecting endpoints into the api slice in other files such as our notes feature our users feature and even our auth feature but today we need to do something here that will allow us to use our jwt access and refresh tokens and the first thing we need to do is go ahead and define a base query so i'm going to come right here on line two get a little extra room and paste in a base query that we can break down and see what it's doing notice previously we assigned our base query right here in the api slice and it is fetch base query now we're going to use this base query instead and since it has the same name as the object key right here so it matches we'll just go ahead and remove all of this and use the comma so we don't have to say base query colon base query we can just put in base query and the comma into the object for create api now let's look at what this does we're putting fetch-based query here so we're setting our base query equal to fetch-based query previously we're just providing this base url notice right now it's localhost port 3500 and that's what we're using in development we would need to change that upon deploying but then we want to add some other things as well one is to put credentials and include so that's an important thing to add and that way we'll always send our cookie remember we have that secure http only cookie that contains our refresh token so when we need it it will be sent but also we need to prepare the headers and that is a specific thing that's available to the fetch based query and the first thing that gets added to it i said specific thing i should say specific function that we can put here with our fetch-based query and the first thing we pass in the first parameter is the headers and then it has an api object now this api is specific to prepare headers one thing we can destructure from that is get state so we could say api here and then put api dot get state but i'm just destructuring get state right here and that allows us to get the current state of the application so notice i'm using git state i'm calling that and then i'm looking at the auth state and then i'm getting the current token that we have and i'm assigning that token so if we have a token then we're setting the authorization header notice we're using the headers here that is the first parameter and we set authorization and then we pass in that specific format that is expected it starts with the word word bearer with a capital b then there's a space and then you have your token and so that sets our authorization header and we simply return the headers here from our prepare headers function now this is applied to every request we send i'm going to save this but before we start our app i want to point out that i am also running the code from lesson 8 which is our back end rest api and that's the last time we worked on it notice it's running here in a separate instance of visual studio code so our rest api server is available to our react code that's in this new lesson 10 repository so i'm going to go ahead and press ctrl in the backtick open up a terminal type npm start and we should see our application start fairly quickly in chrome okay with the react application running i'm going to drag it to full screen and then i'm going to press ctrl shift and i to open up the dev tools and notice i'm looking at the network tab instead of the console so find your network tab in your list of tabs and we want to see the requests come in and see what happens also i should note that in that backend code and i can pull it back up quickly that from lesson 8 that we're running i set the access tokens to expire in 10 seconds i set the refresh token this is just for testing purposes to expire in 20 seconds and so this will just help us see what happens much faster normally we will set this to where the access token expires in 15 minutes and will set the refresh token to seven days for our deployment for this specific application however i wanted to point out we're at 10 seconds and 20 seconds right now so let's go ahead and log in and now i'm going to put dandy our stakeholder in his login once we're logged in you can see we immediately had a auth request and then we pre-fetched the notes and the users now we can view the tech notes and we already have a 403 forbidden because we were past our 10 seconds so let me log out and do that again because we'll need to do it fairly quickly and now let's view tech notes and we have our tech notes but it expires fairly quickly now we're not using the refresh token yet and remember every 15 seconds we have the polling set so our tech notes re-queries that information and so we should see it expire and we will get a 403 forbidden and that's what we see here in our network tab so we are using our access token and we can briefly see those for 10 seconds right now before it expires when the next request goes out which is actually in 15 seconds we get this 403 so now let's make some changes and we will go ahead and start applying the refresh token as well i'm going to close the terminal window and now underneath our base query that we created and we do need it i am going to paste in a query wrapper that we create here and this is going to be called base query with reauth now this is going to accept args which are going to be the arguments like we're passing in essentially to our fetch-based query here it's the url and things like that this has its own api so not to be confused with the api object i talked about with prepare headers that's a separate api object but a base query has an api object also that we can use and then there is an extra options object and we just pass all of these in even if we're not using them so we see args api and extra options now i put console logs for each of these now you could uncomment any one of these and you could see what we would get but extra options would be undefined unless you passed in a value and here i have the example of shout being the key and true being the value but these are just examples i wanted to leave those in just for the purpose of this tutorial now we set our result with the keyword let equal to await base query that we previously defined and we pass in our args api and extra options just like we have above now this would be the result that we get this result right here that we get from the first request so we have used our access token as defined up here with our base query so it passes the access token but now notice we're looking for a 403 so if we get an error status of 403 i'm logging sending the refresh token and after we send the refresh token which i'm commenting right here i'll press ctrl b so we can see all of this then we're going to get a refresh result so notice now we're going to await the base query and our args that we see here is a new route to go to it goes to the auth refresh and then we're passing in api and extra options again what we expect to get as our refresh result is data and the data should hold the access token so now notice we are dispatching set credentials and we are spreading in that refresh result dot data we could destructure the access token from there as well but i did it this way in this place also with set credentials being used there we need to go ahead and import set credentials at the top so before i forget to do that let's come back up to the top and put in our set credentials that we defined in our auth slice that was that action creator and then it sends the payload and sets that token in our redux state okay now let's scroll back down after we have set credentials then we retry the original query notice we're using the base query again right here but we're passing in the args once again and now remember if you're wondering what the args are versus passing in this route let's scroll back up here and you can uncomment these and see but it will be the request url method and body that we previously set so you could double check that with the console log statement if you want to okay that should then retry that original request and we should once again get our data because we've applied a new access token so what happens we try the original access token if it doesn't work and we get this error status 403 which is forbidden then we send the refresh token and then the refresh token should give us a new access token which is set here with set credentials and then we retry the original query but there's an else if we don't have the data we're going to then set the error status to 403 so we will have a forbidden from our refresh token try as well so we'll have two 403s in a row and then we're setting this message here to data.message your login has expired and we will see that and i've put a specific space after this on purpose because we're going to provide a link after that but we do that in the component where we will use it and then we'll return that refresh result which would be the error that we're sending on otherwise down here at the bottom we're returning the result which is what we hope to get after we retry that original base query or it was up here and it was successful and we didn't need to have the check for the 403 if that was the case this is the original query that might succeed without all of this if the access token hasn't expired i hope all of that makes sense and it really helps to understand what happens with an access in a refresh token and it might help you to go back to lesson 8 and review that presentation on the jwts that i gave in that lesson now there's one more change we need to make and that's that we're not just going to use this base query anymore we're going to use our base query with reauth so once again this base query just becomes the key for the object and then we provide base query with reauth as the actual value here that we're using as the base query with these changes saved let's make sure our app is still running yes i opened up the terminal that says compiled successfully let's close the terminal drag visual studio code to the left our app is on the right i'll drag chrome over for a full screen open up devtools so we're on the network tab once again and let's get ready to log in and see what happens now with these new changes in place that also use our refresh token we're logged in we've got the auth notes and users let's go ahead and go to the notes page we've requested notes again now because that used the get notes query that was on our notes list page and that starts a 15 second counter before that polling interval requests that data once again and we set that and this is what we see happen it failed because our access token only lasted for 10 seconds but the refresh token lasts for 20 seconds so we used the refresh endpoint we got a new access token and requested the notes again but now the second time we request the refresh token has expired at 20 seconds because this is now 30 seconds later and so our notes didn't succeed and then the refresh token did not succeed and now we get that your login has expired so at this point it would be time to log out and then we could go back to the employee login if we needed to so when we extend those tokens to 15 minutes and seven days of course we won't get kicked out so fast but this shows us that they are working what happened was we pre-fetched all of our data we hit the auth in point we got the notes and the users then when we went to the notes list it requested that data once again because we loaded that component and then after the access token expired we used the refresh endpoint and we got the notes data again that was when we polled at that polling interval of 15 seconds to once again refresh that list and then the second time we pulled which was 30 seconds the refresh token had also expired and so we see those failures there and then we hit the log out but there's something to note here we're continuing to request the notes and getting a 401 every 15 seconds this is something i discovered and i might report this as a bug i'm not sure that it is though so i need to dive into that but i did figure out a fix for it so now let's look at that i'll go ahead and close out the dev tools let's go back to visual studio code and look at how we can prevent that request from continuing to repeat after we've logged out let's open the file tree as we're finished with the api slice so control b i think i pressed control back tick there and open the terminal by mistake but what we want is the file tree and now inside of the file tree just so we can identify these queries better and discern those from the actual prefetch queries let's go to the notes list and the users list and instead of this undefined we put in as the first value of this use get notes query or the first parameter i should say let's go ahead and put in notes list and that will give it a label and now let's do the same thing for users on the userslist.js file we had undefined let's go ahead and put in users list and we'll be able to see these in react dev tools and just tell these queries apart from the ones that are used in the prefetch component and now let's go up to the auth folder and we want the auth api slice this is where we have our logout request and then we have our onquery started function and what we're doing here is waiting for query fulfilled let's go ahead and uncomment this let's put this all on the same line so you can see that message we get back which will say the cookie was deleted and we can log that right there but after that what is happening is we are logging out and we are resetting the api state but then it's still hanging on to that one query whenever we log out from our users list component or directly from our notes list component i noticed when we logged out from the other components or if we chose the same logout button of course it's always in the header from other components we do not have this issue but we're on when we're on the users list and when we're on the notes list we do now those queries that are created by rtk query are supposed to unsubscribe the components when the component unmounts so we're missing something it's taking just a little bit of extra time and that is actually what i did to solve the problem for this application i just went ahead and put in a set timeout function and then we'll have this anonymous function inside of set timeout and i put the dispatch of the reset api state inside of a set timeout and you could play around with the interval or the actual delay time it's not an interval so much because it only happens once i just set it to one second and that should give it plenty of time to go ahead and confirm or realize that it has unmounted that list component whether it's the notes list or the user's component and then it can reset the api state and then it gets rid of that subscription so like i said i might submit this as a bug i'm not sure that it is a bug though it might be something that i am not realizing that i'm not doing in the correct order but i think i'm doing this correctly with the onquery started to follow up our action here otherwise i would have to import use dispatch and whatever i wanted such as my logout action creator or my set credentials action creator into a component every time i wanted to use it but this way we can put it into the actual request here that we have such as send logout with our query and then using onquery started this will be called wherever we would call this mutation and likewise you will see when we create our persist login component i did play around with this and imported use dispatch and that actual set credentials action creator there and i still had this issue so this is the place that i have found to solve the issue with set timeout for now with this in place let's go ahead and try this again and if we need to we can even look at react or redux dev tools and see the difference so i'm going to once again open this up and we'll log in right now it is still currently subscribed as notes so we saw that failure but here we have auth notes and users we've got everything here we go and we've requested the notes again now let's look at our redux component and we can see some state here as well and this is where we want to go to see all of this state and here's the subscriptions if i could get it to stop there we go so there's our subscriptions we have two undefined those are the pre-fetch but then here's the notes list that we did label and define and now if we unsubscribe let's look at our last state here we should no longer be subscribed to everything that we have here let's see well we're still getting the pending and rejected from that previous subscription i believe let's go ahead and try this again and this time i'll refresh the app now we have no state whatsoever let's go ahead and log in and now that we're logged in let's look at our current state here i really would like to drag this over so it's a little bit larger have a little bit more room to work with everything there we go now our api comes down and there's our subscriptions we can come to the end let's go ahead and look at the tech notes we've got the tech notes now let's log out and we have no subscriptions we can see where we logged out where our state was and we did have subscriptions we had get notes undefined and get users undefined that came in from our prefetch component get notes was from the notes list component then we have our subscriptions here that we're removing i believe and these are easier to see in the other view but then once we get down to the reset api it removes all of them so this was actually different fulfilled mutations or not i believe you know there it removed those subscriptions one at a time there we can see those removed when we're highlighting each one of these that remove the mutation there it removed the notes list subscription and there it cleared out everything with the reset api state before we did not have that so that's just important to note if you don't put in that actual set timeout with a little bit of delay you will have that one subscription from your get users or your get notes that is still active okay with that workaround now in place let's drag this back to the left and once again look at visual studio code we are using the jwts now we have the logout working correctly and we're ready to work on persisting our login state even when we refresh the pages i'm going to drop the features directory down and what we need to do is create a new directory called hooks and inside the hooks directory we're going to create a custom hook named use persist dot js this is a simple component i'll paste in and review with you and it's very much like a used local storage component and if we were actually going to use local storage for more things in this application i would probably create a use local storage component and then we could still persist and do other things with it but this is specifically for our persist data so we have use persist we're setting persist and set persist with use state and we're looking at our local storage and if persist does not exist in our local storage it is simply false to begin with we're using the use effect hook as well and when persist changes we set that value to the local storage and then we're returning persist and set persist so we will use this very much like a use state hook but it's specifically for our persist data so let's go back to the file tree now and we want to open up the features directory open up the auth directory and choose our login component there we're going to import our use persist hook that we created at the top and then underneath our state we can use persist as well so we'll say const we'll have persist and set persist and now let's set this equal to use persist and now i'm going to scroll down to where we have our handlers and underneath the handle input and handle password we're going to handle the toggle of our persist and what we're going to do here is just use set persist take the previous value and set it to whatever the opposite is because it's really just going to be a check box and now we'll scroll down to the bottom of our form and we have a button at the bottom right now but we want to put this underneath the button and this is going to be that check box just a toggle so our label says html4 persist and we have a class name applied from my css and then this input right here is a check box it has a class name of form two underscores and checkbox remember these class names go back to my css if you're using my css the id is persist which must must match the html4 attribute that we have up above and it is a controlled input so we have an on change with handle toggle and checked is equal to persist and notice i'm labeling here just trust this device next to the actual input the check box that we're providing let's save these changes and we didn't save use persist yet either or if you hadn't go ahead and do that as well so we've saved our use persist hook and the changes to our login js now we need to create a persist login component before we do that i want to highlight there is just one change i added to my utility classes of the css file note this class error message i'm now choosing any link inside of the error message because we're going to provide one and i am just styling it adding the underline and the error color so go ahead and grab these the entire css file if you want to just note that i have added a change to it from the previous lessons and now inside of the auth directory let's go ahead and create our persist login component this is the component that is going to help us remain logged in even when we refresh our application so i'm going to paste in the imports first and we'll take a look at those there are several so note we have the outlet from react router dom we're importing use effect use ref and use state from react we're importing the use refresh mutation that we created in the last lesson in our auth api slice we're importing the use persist hook that we just created we're also importing use selector select current token from the off slice and then link from react router dom and now that i'm looking at this link was a late edition let's go ahead and cut that out and let's just put link right after outlet since they both come from react router dom and we can remove at least one line out of all of those imports with the imports complete let's go ahead and start our component with rafce the es7 snippet that helps us go ahead and create a quick component a functional component and now we have our persist login component and let's start with some of the state at the top and also a use ref so notice we're just pulling in persist and not the set persist from the use persist hook we created we're pulling in the token using our use selector and the select current token selector from our state and that would be the current token that we have received that will give us the access that we need it's an access token we're also defining effect ran and this is something i'm doing specifically for react 18 and i do have a tutorial on how to handle strict mode in react 18 and that's exactly what this is going to be for we're setting this use ref to false right now and that is the effect rand value now we're going to have true success and set true success i separated this out because it is something that's a little unique also that we'll need to talk about next we'll go ahead and bring in our refresh mutation and this looks like many of the other hooks we have used from rtk query so we have our refresh function and then we have several states one new state to notice that we haven't used before is is uninitialized that means the refresh function has not been called yet and that's another state that we're going to use and now i'm going to scroll up for some more room and after our use refresh mutation hook we'll go ahead and put in our use effect and we'll cover this there's quite a bit to cover here as i'm doing something that was covered in a separate tutorial about handling react 18 strict mode so that's what you see first we're using our effect ran which was the use ref defined up here with the initial value of false now we have to get the value from the dot current property so now i'm saying if effect ran dot current is true now the first time use effect runs it will be false but in strict mode what happens to every component is they mount then they unmount and then they re-mount so use effect runs twice when you're in development using strict mode so if effect ran dot current equals true will only be true the second time and that's because we're going to set it to true later on now next it says or process dot env dot node underscore env not equal to development so if we're not in development mode it's going to go ahead and do this as well so that's because react 18 strict mode only happens in development so if you have that in effect in your index js and when you use create react app it is in there by default so it's good to know this so this will have a problem actually if we do this twice and usually it's okay and components won't have a problem but this does create a problem if we're going to use that refresh token so we won't only want to send it one time and before i get into the verify refresh token function just to continue on with this strict mode notice using the cleanup function here so after use effect runs the first time the cleanup function sets it to true the effect ran dot current equals true and then use ref will actually hold that value even after the component unmounts and remounts and so that will be okay so when we come back through this will be true now you see our function verifying refresh token or verify refresh token it's an async function and notice i'm just logging to the console here so we can see it happen verifying refresh token and i've got a try catch block now what i did was comment out the response because we don't really need it here we're going to set this response in our onquery started back in our auth api slice but i wanted to go ahead and leave it here in case you want to uncomment it and go ahead and log that console here or log the access token to the console i should say you can do that here and when i first put this together i actually imported use dispatch and then i imported set credentials and that is the action creator and we des dispatched that action creator right here but i think it's going to be better to do that in the auth api slice and that on query started much like we did with the logout action creator so we're going to await the fresh refresh right here but then we have a problem and i didn't think about this at first but we can have that is success status from our use refresh mutation hook it can be successful before those credentials get set and that happened to me when i was dispatching it here and it still happened to me when i used it inside of the on query started inside of the auth api slice so either way so what i needed to do was add one more piece of state so that's why you see this set true success i needed one more flag to say yes we have got the data and those credentials have been set and it really it just needs that extra little bit of time to work it doesn't really make sense it's not something you would think of at first but then when you try it the way you think about it when you just wait for the is success you realize when it's not working that you just quite haven't given the credentials time to be set and then be used when the request is sent so by setting this other piece of state right here we get that extra little bit of time and so that's why i just called this true success so once we set that to true as we have that in state above right here on line 14 that's why i set it aside because it just needed a little bit of explaining once we set that to true we should be ready to go ahead and display everything inside of our components and this persist login component is a wrapper it's wrapped around everything that we want to persist that we need the token for and now that defines our verify refresh token function and notice after that we say if there is no token and we have checked persist so if persist is true essentially then we're going to verify the refresh token now why do we say if there is no token well that's what happens when you refresh the page and the state is wiped out you have no access token or any other state at that point so we need to verify that refresh token and what we do with that endpoint is just send that cookie back and that contains the refresh token and then it gives us access to all the other state because we get a new access token one more thing to highlight before we're finished with use effect and that is this comment right here so this disables some warnings that will tell me i need several things inside of my dependency array here but i really don't because i only want this to run the one time when this component mounts and it makes this check so if you put in this line eslint dash disable dash next dash line then you will not get those warnings now i'm going to scroll up and instead of returning the div that we have right here i'm just going to say content and we're going to define some content and it's really going to be a larger if-then statement than is needed but i wanted it to explain some things so you could condense this down after you understand what all is happening but i really thought i needed all of these different else's here to show what is happening so the first thing we're going to do is just say if persist is essentially false if we're not wanting to persist our login then we're going to say no persist in the console and we're just going to set the content equal to the outlet so that's fine we don't want to persist the login it won't have an access token it will tell us we're not logged in if we refresh when we're on a logged in page a protected page the next is the is loading state so if that is true maybe we've told it yes we want to persist but we don't have a token because our refresh mutation will only get called if we don't have that token so that's the only time there would possibly be and is loading so then we could display the content of loading while that is true now we might have an error if persist is yes and token is no as well but maybe we get an error so we're going to display that error and this could happen when our refresh token expires so we get a 403 not only from the access token but also from the refresh token and then we're going to go ahead and use that link from react router that says please log in again and we're going to display that right after our error message so we should see that all in one line finally this is the one we want is success is true but remember we also needed to wait for that true success or it just didn't get time to set the credentials so here we've got persist is yes and yes now we have a token and everything is ready to go but also there's the possibility right when this component loads that we do have a token but we haven't yet initialized that refresh mutation function so this could also be what we see and this has token and uninit is going to the console and you'll probably see that because that should be what happens first or also just logging is uninitialized so you can see what that value is it should probably be true at that point and this would also just return the outlet now after you take all of this in as i said some of it could be condensed i just wanted to show you each possibility inside of this if and then else if statement and there are several possibilities to take into account now let's go ahead and save this file let's show the file tree once again and go back to our auth api slice in the previous tutorial we went ahead and added our refresh mutation right here however i mentioned we did not put in the on query started yet here and we need to do that so let's put a comma after the query and then let's go ahead and put in our on onquery started and you'll see why we need it here we have onquery started much like above we used it here in our log out as well and we're once again pulling in the dispatch and the query fulfilled we're once again getting the data i'm going to go ahead and log the data here which would be the access token and here you can see i'm destructuring the access token now we need to import set credentials at the top as well so let's make sure we do that before we forget and it comes from the off slice just like log out so i'll put set credentials in there and then if we come back down and look at this we're taking our dispatch and we're going to go ahead and call the action creator set credentials and pass in that access token right here and we're doing this here so we don't need to import use dispatch in the action creator in every component that we want to use it in now time we use our refresh mutation it will go ahead and set the credentials for us as well and with that complete we are ready to go to our app.js and import our persist login component so we will import persist login there it is in our list and once we have that let's scroll down and we're going to wrap this around everything just like we did our prefetch component so i'm going to click on the line of the prefetch component and press shift alt and the down arrow and then i'm just going to change the top one we want this to wrap around the prefetch as well to persist login and then i'll scroll to the bottom and where we have our closing route i'll do shift alt in the down arrow to get another closing route when i save it should imply the or apply the indents and we see that so persist login is now wrapped around the prefetch and the dash layout component and of course everything else that's inside of those and with our changes all saved let's drag this to the left and it looks like we're having a hard time finding this hook that we created let's see what's going on with that and yes i've got the hook way up here the hooks directory needs to be inside of the source directory sometimes i miss that when i create a new directory so we're inside of the source directory and that is where we have the features directory we have the hooks directory the config directory and so on so if you were following me and had it outside of the source directory please move the hooks directory inside of the source directory okay let's drag this to the left once again no more error that looks good let's drag our screen of the browser over so we can see everything that we want to see now and what we're going to do is clear this out and we're going to refresh everything let's go to the network tab once again so when we log in we're going to have dandy and sign in and we've got our auth notes and users let's go to view tech notes we're still good let's refresh and our tokens haven't expired and notice what happens when we refresh we hit the refresh endpoint we got notes and notes users from the prefetch as well one of these notes came from the use get notes query now i haven't changed our back end so it's going to time out fairly quickly so let's go ahead and change our back end now as well i'll pull this back up and let's put the proper times here so we'll say 15 minutes for the access token and we can say seven days for the refresh token so that shouldn't expire but remember there's a second spot for the access token because our refresh endpoint issues a new one so we need to scroll down and find that other 10 second spot and change that to 15 minutes as well now those shouldn't time out on us and we'll be able to test everything just a little bit better here so now clear this out go ahead and log out here and everything should be clear but i want to go ahead and refresh just start with a clean slate now let's go ahead and log in again dandy [Music] and notice i should go back to the home page here i'll log out one more time so we can look and i log in notice we have the trust this device now with the check bar and if you want to check that you can go to the application tab and then you're in local storage local host 3000 persist is true right now we can uncheck it you won't see it change here you need to actually right click choose refresh now it's false if i check it again and i refresh again now it's true so that's how you can check that now i'm going to go back to the network tab refresh all of that or clear it out at least and now we'll say dandy's login one more time we've logged in he hits the auth endpoint prefetches notes and users let's go ahead and look at the notes so now we had the other notes request now if we go ahead and refresh we're still good we hit the refresh endpoint one of the notes was pre-fetched and one was from the notes list page and then we have the users prefetched as well we can even go in to one of the specific notes and we can refresh and we still have all of the data and we're still logged in so now that we're using our jwts and our persist login state is in place we are ready to apply role-based access control and permissions and that is in the next tutorial remember to keep striving for progress over perfection and a little progress every day will go a very long way please give this video a like if it's helped you and thank you for watching and subscribing you're helping my channel grow have a great day and let's write more code together very soon
Info
Channel: Dave Gray
Views: 21,108
Rating: undefined out of 5
Keywords: JWT Authentication, persist login state on refresh, persist state, jwt tokens, jwt token authentication in react js, jwt, jwt refresh token react, react login authentication with jwt access, jwt token authentication react, jwt authentication with refresh token, MERN stack, refresh token, access token, redux jwt, react jwt, mern jwt, react.js jwt, auth, authentication, mern authentication, redux auth, redux authentication, redux, mern stack, persist state on refresh react, rtk, js
Id: 9YnZHQsWmJs
Channel Id: undefined
Length: 43min 3sec (2583 seconds)
Published: Tue Aug 30 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.