Authentication in React, Redux and JWT #19 | MERN Stack Tutorial With Auth

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up guys so in this video we are going to perform authentication in react and redux so we'll have a form where we can sign up our new users and then we'll have another form where we can log in registered users and once you are logged in you can be able to sign out from the application we will also be making use of jwt which stands for json web tokens and local storage for persistency so we'll be able to get a token from the server and then store it at the record storage and the application state in order to know the currently logged in user and then we'll be able to perform conditional rendering depending on whether a user is logged in or not now in case you are not aware this video is a continuation of the ongoing monster series in my youtube channel so i leave a link at the description section below to this particular series or playlist so that you can see how we created our back end using express mongodb and also node.js so we are able to create all the card operation api endpoints and also the odd api endpoints in this particular video we also created the uh ui using react react router a material ui and we were able to perform crowd operations using react and redux hooks so right here i have the right version of the application where you can go to the sign up form and also the signing form and sending a new user and i'll also leave a link at the description section below to this live version of the application so that you can test it out okay in case you're new here my name is charles i am a javascript developer at coffee lava and i create coding content here on youtube now that sounds awesome so please make sure you subscribe so that you don't miss any of my futures videos so in case you want to reach out to me you can do so through my twitter which is at your chance or you can leave a comment at the comment section below now to start with we are going to create an action creator for handling sign up okay remember we are using redux and right here we had our to do actions uh up to where we reached uh and we were able to perform all the card operations but in this video i want us to move on to authentication so from our actions i'll be creating a new action creator for signing in the users and also registering the users and performing all those odd operations so i'm going to say all actions.js and i'm i'm going to come to the to do actions and copy this first portion of the to do actions up to this uh get to those action creator i will copy that and then go to the odd actions and i'll paste everything in here so we will need to make use of axios to perform http request we'll make use of this url which is coming from the api folder right here if i click this index.js you'll see that the url is simply our server endpoint which is localhost 5000 stroke api so i'm grabbing this and then uh coming to the other actions and importing it here we'll make use of a react dust file for test messages and then we need to customize this action creator to fit our needs so the first thing that we can do is to rename it to sign up so right here i'll say sign up and then with the help of redux dunk we'll be able to return a function in here and be able to perform a http request or a network request i will have access to this patch for continuing the dispatch of our action and then we'll use axios dot post okay so this time we are using the axis.post because we are creating a new resource to the database which is a new user so right here we'll say axios dot post and then the url here will be the url which is uh this one here http localhost 5000 stroke api and then we will add something on the front end so that to hit our odd api endpoint for signing up the users so instead of stroke to do's we'll say stroke sign up and right here we will be getting in a user uh when we dispatch this action creator from our signup form so right here i'll get in a user and then we can store this user now to the backend so right here when i say user this user will be received by our api endpoint and the user will be saved in the database and then once the user is saved we will be automatically get logged in to the system by getting back a jwt token so what we get back from this post request is a token which is a gwt token so right here i'll say token and then we can dispatch an action here and the dispatch here will be sign up so sign up and now we can access this sign up from our users and update the state accordingly but right here we also need to dispatch the token itself so right here i'll say token and uh i'll use a full column because the token will be actually available in token dot data so it will say token dot data and that token will be stored in this particular property called token okay in case there is an error we'll be able to catch that error and log it to the console and also we can test it right here so i can use react justify i'll say toast dot error and i'll say error dot response dot data so right here i'll use this question mark in case uh we don't have the response uh there there will be no error that will be drawn okay so this is a safe way offroading the data from our error okay and then we can position our toast right here i'll say position a full colon i'll say toast dot opposition which is this one and then dot bottom right uh we have a suggestion there so yeah this is it but for persistency i want us to also save this token which we are getting from the backend to the local storage okay so in javascript we have access to an object called local storage so just uh after this one before we dispatch the action we will say local storage and we have a method called set item just like that and then when i invoke this method the first parameter here uh will be the property of whatever we want to store at our rocker storage so the key and the value pair is what is happening here so right here you have a token which is our key and then the value will be token dot data just like we did here okay the top that the token a string is available in token dot data so right here we pass talking dot data and now when we successfully get a token this token will be stored at our local storage and this is an action creator now for uh signing up a user okay this is all we need to do the next thing we need to do is to dispatch this uh action creator from our signup form so what i'll do i'll go to the signup form uh in our components i expand auth and then go to sign up so for the sign up form uh we need to make use of our state and also uh our action creator for us to successfully get the values here and send them to the back end so to start with uh i'll may i will import use state from react right here so i'll say use state and this is not uses its use and then after we uh we declare our component here inside here we'll make use of the user state so i'll say const the structure user from the user state here and then set user and this is the method that we'll use to update our state here and we set it to use state i invoke this and in here i can pass default values for our user state okay so we expect a user to have a name so i can default that to an empty string we also expect a user to have an email and i'll default that to an empty string and also we expect the user to have a password and i'll default this to also an empty string okay now i can come to each of these fields and uh update each of these values depending on the field okay so the first thing that i'm going to do is that i'll set a value a prop here so i'll say value will be equal to i use this curry brackets and access the name so it will be user dot name right here user dot name and then now we can update the name using unchanged event so right here i'll say on change i will be equal to as this curry brackets we get an event here and then i make use of set user i invoke this i spread the values of the already existing user which are these are values here so in here i spread the values for the user but we want to update the name then the name field so right here i'll set the name to be a dot target dot value yeah i guess that's correct okay when you type on this particular field we will update the name to be equal to the that particular value that you type in okay so we will do a similar thing for this other fields and uh i like copy pasting to make my work easier i'll copy that paste it here change this to user dot email and then we use the set user we spread the properties but the thing that we are changing here is the email property i got the password after this i paste this one and then i use the user dot password and then i update the password right here just like that so all our field are set now i need to create um a helper method which will be called whenever we submit this form okay so right here i'll have an on submit event so on submit and we will call a helper method and we can call it handle submit just like that we haven't created this method yet so let's come at the top here and create the method just before our return statement i'll say const under submit which will be equal to it will accept an event and this is an arrow function just like that and the first thing that we will do is to prevent the default action of submitting a form so right here i'll say a dot prevent default so this will prevent the browser from refreshing or the page from refreshing and i invoke that and then after this is where we can perform a dispatch of our action creator so to dispatch an action creator we will need to make use of some redux hooks and uh the specific redux hook is the use dispatch hook so right here uh we can import use dispatch and this will be coming from react redux so i import use dispatch and also i import the use selector hook so we'll use this use selector hook later on when we want to select some piece of state from our product store so use selector and all this will be coming from react redux react hyphen redux and i forgot uh from here and the spinning for this one ah i guess that is right okay so this is what i am interested in they use dispatch hook okay and it's coming from react redux so i'll come just after our classes here and i'll set a constant called dispatch and i'll initialize the use dispatch hook this patch i invoke it just like that okay now we can make use of this dispatch inside our hand of submit helper method so right here i'll say dispatch i invoke this and we should now dispatch our action creator just right here okay but we need to import that action creator from our old actions so right here let's import our action creator i'll say import the sign up action creator and i need to drop this inside the curry brackets because these are named export so if i come to the odd actions here you can see export cost sign up so it's a named export and we should use this cutting brackets to destructure it okay i'm lost we are here so all this will come from our action creator which is uh very far we need to get out of the components folder so that we go to desktop so i'll use this up one directory another directory we'll go to the store and then we go to actions and then right here you should get a suggestion for other actions if we don't get uh something is wrong yeah actions that's perfect and then now we can dispatch this action creator in here where we are performing a dispatch so i'll say dispatch sign up i invoke it and it expects a user so right here i'll simply pass the user which is this user and once we type at our fields this set user will correctly update the properties of our user so when we perform a dispatch when we click the submit button this function will be called sign up uh action creator will be dispatched and then it will receive that user right here and then we'll use adjust.post and then tap the end point right here and pass the user to the body of the request so that our backend can save that user to the database once we successfully save the user we then sign in from the backend using jwt and what we get back is a token and then we save this token to the local storage and this will help to have persistency for authentication in our application and then after that we continue the dispatch by dispatching an action of sign up and then the token and we can access this now at our reducers and correctly update the state okay but before we go to our reducers i want to come back to the signup form once we perform a dispatch i want us to reset the form values by changing the state to the default state and this will affect each value right here okay so if we set the name to an empty string the value will be empty so right here i'll make use of set user and uh i invoke that and pass these values in here so i'll just copy them and paste them in here this will just uh this will just reset our form so i will save this and pretia will correctly format my code i guess this is okay for this form at the moment and all we need to do now is to update our state using the uh of the user so in our reducers we have root reducer and to do reducer so we can add a new file for the user so right here i'll say earth reducer just like that but the js and then this odd reducer is supposed to be just a function so right here we will import toast from react justify for our test messages just like that and then we will import a jwt decode so this is something that uh you'll need to install so if i come right here i had already installed it and uh let me see yeah yeah i am at my front end and i perform this action and pmi jwt decode and this jwt decode will help us to decode our json web token which we are getting from the backend okay so please install this and then we need to import td card right here so i'll say import jwt decode and this is from that package which i am assuming you have now installed gwt hyphen record just like that and i think i made a mess did i install uh this package correctly yeah it's jwt hyphen d card okay it should be that way now you can import jwtd card from jw td card now right here we should have a function which is our output user so i'll say const of reducer will be equal to it have access to the state and the state uh we can set the state to have an initial value so this one will be equal to let's call it initial state initial state and we'll also have access to action and then this will be an arrow function so we pass it just like that and uh we don't have this initial state at the moment and i misspelt it initially i think it's written that way now so let's set this initial state which will be an object for our default state so right here i'll come and set a constant call it initial state and then i'll set it to be equal to an object so for our state our earth state we expect to have a token and we'll get this token right here from our local storage so remember right here we saved a token at the rocker storage and now we can access that token from the local storage and store it in our state by default so this will have some persistency whenever we refresh the page or whenever we come back later and try to access our application we already have a token at the local storage and we can get that token and set it to our state okay so right here i'll use the local storage object and then access the get item method and now right here we only need to pass the key for that item okay and we set a key of token so if i come to other actions we set a key of token which will be equal to this token dot data so this is the token and then uh we will have the name i'll set this one to null we'll have an email a i'll also set this one to null and we will have an id so i'll say underscore id and this will be the user id okay or also set it to now now this is the initial state okay this is the initial state for our application and we are setting it to be the default state right here state to be equal to the initial state and then we have access to action now we can switch through the different action types and update the state accordingly right here so right here i'll say switch action dot type and then in here is where we can go through each case and the case i am interested in right now is the sign up case so sign up and that case is the one that we dispatched right here yeah i'm a copy paster i'll come here and paste that right here so this should be the same as that uh action that we dispatched from actions so for the case sign up i will use a full colon and then we will toast our welcome message so right here we can say toast and we can enter a message here welcome and then i can position this to be at the bottom right so position toast dot position should give me a suggestion but it's not okay bottom right but we also want to include our user to the uh orb state so what i can do at the bottom here i'll now make use of jwt decode okay and i'll say const user will be equal to jwt decode and then i'll pass the token which is action dot token okay so this action dot token is the one that we passed right here action dot token which is equal to our token and once we record that token we will get a user and i'll show you how this is working on the jwt website so that you can correctly understand it but the user will have this uh properties name email id and uh whatever property we included at our backend okay and now that we have that we can update our our state like like this so we can return an object uh we spread the initial state which is this one right here so we spread the initial state comma and then we can update each of these properties okay so let's start with the token so the token here we will update it to the token that we are getting from the backend so we will say action dot token and then we update the name which will be user dot name we update the email which will be user dot email and also we update the id which will be user dot underscore id just like that so if i save this uh i think preacher should format the card and this is more redouble now so let me take you through what is going on once we submit this action sign up our other reducer will check for case sign up and then we test a welcome message we decode the token action dot token and get back a user with this properties name email and id and then we can update our state from the initial state here to this particular state where we can now have uh these properties in our other state okay and then after this uh we should also perform a default case right here we can say default for colon we simply return the state return state now we need to export this all right user right here so i'll say export default and then odd producer and once we export it we need to use it in our root reducer so that our application is aware of it so i'll come to the root reducer and import our odd reducer i'll just duplicate this one using alt shift and the bottom arrow and then i'll import auth from auth reducer and then right here we will add off to the state so i'll use a comma and then off and right here i'll say of reducer so our off here would contain uh the state of our odd reducer which is this one now token name email and id and we'll be able to access this state from any other component in our application because now this one is in redux store okay so yeah yeah that's it that is how we can perform sign up and the only thing that remains is is to test our application and see whether we'll get a token and add it to the state and also to the local storage so uh i'll come back here and start my application using npm start and this might take a while so npm start and then another thing that i want you to have on is the server server should be also running so whenever you have your backend run your server using nodemon okay because we need to access the server using this api right here index.js you need to access the server on localhost okay so make sure your server is also running so the app failed to compile and it's because we have two errors one is in our all actions and the other one in our odd reducer so to fix this error we can go back to the code editor and the error is because of our toast dot error method here the first parameter should be our response or our error message and then the second parameter is our option for positioning the test message so i should cut the entire of this section and include it inside our our era method are brackets so i'll create a space and paste everything right here so this is what we have this is the first parameter and the second parameter i'll save that and then the second error is in our odd reducer so right here instead of user i wrote use so i should change this one to user and that should fix the second error also i would like to log the state to the console so that we can see whether we will get the user at our state so i'll go to the sign up form and i'll make use of this uh redux hook which we had imported earlier called user selector so just after dispatch i'll say const state will be equal to use selector i invoke this what we get right here is the state and we can return this state so that it is stored in our constant here so state and then an arrow function and we return the state so now we can lock this state to the console right here and say console dot rog state so let's test our application i'll come back to the browser and refresh this page so now our application is running and when i open the console right here i can come to this arrows and then go to application here and you'll see we have a section called storage and we can see whatever is stored in our local storage so at the moment we don't have anything stored at our rocker storage it's empty but because we used our local storage in our application once we sign up a token should be added right here and when i look at my mongodb database you will see that our users we currently are don't have any user so let's test the application i'll enter a name and email and also a password and then click sign up and you'll see we get this message welcome message which we included in our reducers and then our token is added right here so if we copy this token and go to json web tokens website we can be able to record that token at the bottom here we just replace the entire of this token with what we have okay and when i paste it here you can see at our payload we have uh the recorded token and uh so we have a user id a name an email and when the token was created and this is what our jwtd code is doing at our odd reducer so this jwtd code we call it and pass the auth token right here and we get back a user so this user will have an id a name and also an email so this is what was happening with our jw td card and we can be able to add the user now to our application state so we had plugged the state to the console so if i come to the console right here uh you can see we have some log messages all these log messages are happening when we enter a value in our form because each time we enter a value the application state changes but when we expand this and then expand off so we have two uh parameters in our state of and to lose so if expand off you'll see that we have an email we have a name and also we have an id and a token so we are successfully sending up a user and we are also sending them in by receiving a token and when we go to our mongodb database and refresh this section we should see that a user was added in our database so let's see and there we go this is the same same user that we just added using our signup form and you can also see that our password is being hashed and this is happening from our backend okay so we will like when a user successfully signs up and uh get sent in in the application we redirect them to our to-do's right here so to do that i'll go back to the signup form and i'll import something from react router dom which is our direct component right here i import redirect from reactor to dome and then we can make use of it just before our return statement and we'll perform a check if ob dot underscore id exists then we want to redirect the user to the home page so right here we'll say return the direct component and we include the two prop which will be equal to a path which is a home page so if a user is logged in or signed up we will have an id at our state and if we have an id it means that the user is logged in and therefore we will redirect the user to the home page instead of showing them the signup form so right now we haven't defined auth and we should get odd from the state so instead of returning the entire state here we can say state dot up and store that in a constant so auth and then i can get rid of console.rug so right now when we sign up a user and we are automatically logged in we should be redirected to the home page okay and we can test the application so the application has loaded but when i try to go to sign up i'm getting an error a field plop where the prop 2 is marked as required in redirect but the value was undefined and the issue is right here i don't know how this was added but this should not be here make sure this is empty and also at the bottom we don't have that redirect the redirect should only be here and we pass the prop 2 and the path so now when i refresh this one we can go to sign up and test whether we will be redirected to our home page so i'll sign up for a new account i'll enter adam email and then create a password and sign up so welcome and we are redirected to our home page okay when we try to visit sign up right now you'll notice that we can't we can't go to sign up because we already have a user in our state and also we have a token at our local storage but when i refresh the page the earth state will be lost and we can be able to visit the sign up page so we added the token at the local storage so that we can add some persistency in our application in terms of authentication so that even if we refresh as long as we have a token at our local storage we'll still be logged in if we have that token right here okay so to add that persistency we will need to make use of this token by loading the user and that is what we are going to cover in the next section so right now we have successfully signed up a user and we are also automatically logging them in in this section i want us to load a user from the local storage and include them in the application state so if i come to the auth reducer you will see that we are already loading a token from the local storage and this token we had added area using our uh sign up so right here we set a token and then we can load that token from our local storage so once we sign up uh this token will be persistent even if we refresh the page so this token remains at the rocker storage and we can make use of it in this particular video where we'll take it from the application state and then dispatch an action of load user and then we can record that action in our odd reducer using jwtd code and include user that is the name the email and the id in the application state so i'll come back to the odd actions and i'll create a new action creator called load user so i'll say export const load user and this will be an arrow function right here with the help of redux dunk we can return a function i return a function and we will have access to dispatch for dispatching our actions and also we will have access to get a state and we can get the application state from the redux store now right here i'll get the token so i'll say cost our token will be equal to get state i invoke it and then we access the earth state and the property that we want from our other state is our token so now this token is coming from our state and it was added our state through our local storage dot get item so we added here the token to our state and we can get it from our state uh just like this okay now uh we can make use of this token by dispatching it so that we can use it in our or reducer so right here i'll perform a check if token exists if token is not null then we will perform a dispatch and i misspelled this one i invoke this pass an object and then the action will be type of user loaded user underscore loaded and then the payload will be our token so this is an if statement we need to also include an else else we'll simply return now we have an action critter for loading our user and we are getting this token from the state and it was added a state using this particular method right here so local storage dot get item token and we add it to the state and now we can perform a case of uh user ordered so i'll simply copy this user loaded and then the case will be similar to our sign up here so all i can do is say case user ordered and then i include a full column so if this action is dispatched our odd reducer will perform a check and it will see that we have user ordered and therefore it will perform this action first of all it will just welcome message and then it will uh decode the user from action dot token so remember we are passing that token right here so it's action dot token and then once it decode that token it will get those user properties so we will have a name from user.name email from user.email and an underscore id from user.underscore id and uh when we perform a check whether an ob dot underscore id exists in our application uh our application will notice that the user has been loaded and they log the user in so our remains is to dispatch this action creator from our front end so how we are going to do that is in our app.js file now in our app.js we'll make use of the use effect hook so we can get it from react right here and then we'll also need to make use of our use dispatch so we can import it from react redux and the last thing that we will need in order to dispatch that action creator is the actual action creator so i can import the action creator just right here i'll say import load user and this will be from our actions so i'll go inside the store because they are at the same level and then actions and then we go to the odd actions just like that and now we can come to our app i'll create a constant called dispatch and we will load our use dispatch hook i invoke that and then just below here we can make use of our use effect hook now this is effect hook will be loaded after our application renders okay and once it renders we dispatch our load user action creator and then our load user action creator will get the token from the state and we will dispatch an action of user order and then our reducer will perform this check it will see user loaded and it will record the token and add these properties to our application state so let's make use of use effect in our app.js so i'll say use effect i invoke it and pass a function in here so this is another function and then in here is where we can perform a dispatch i invoke it and we dispatch our load user action creator we also need to pass our dependency array here so i'll use a comma and then i'll pass this patch in here so every time we have a dispatch this use effect uh will be called okay so yeah that's it and now we can test our application so i'll come right here and start my front end and also make sure that your back end is also running okay so back end no demand and it's running on port 5000 [Music] now our application has loaded and you can see we already have a token at our local storage so if i try to go to sign up i can't because uh we are already logged in in our upstate we have an odd id and if i try to refresh this you'll see now that we have some persistency with authentication as long as there is a token in our local storage we are automatically signed in okay so now the only way of logging out the user is by deleting this token from the local storage and that is what we will do later with our sign out button we will be simply deleting this token so if i clear this token and try to refresh this page now you'll see that we can visit our sign up uh component not unless now we sign up the user again and they are automatically logged in and we have a token in our local storage so now we are successfully loading a user and in the next section we will see how we can sign in a user using this sign-in form in this section i want us to sign in a user using our sign-in form and our sign-in action creator will be so similar to our sign up action creator so all i'll do is that i'll copy this action creator and duplicate it at the bottom using alt shift and the bottom arrow so now right here i can create some spacing and customize this action creator to fit our sign-in action so first things first is to rename this action creator to sign in and then right here we'll be getting a credits or credentials that is email and password i'll simply call it credits and then we can return dispatch use axios to perform a post request and the end point in this case is signing not sign up and then we pass threads to the body of the request and this now can be received by the back-end api and the user will be sent into the system what we get back is an op token which is a jwt token and we simply set this token to our local storage or save it to our storage the key is token the the token data is token.data or the token itself is token.data and then we perform a dispatch of of an action type will be signing and we also pass a token which will be in token.data and we can access this from our users and update the state accordingly and then right here we catch any error we log an error to the console and also uh twist the error as a message now this is all this is all we need to do for the sign-in it's just so similar to our sign up all we need to do is to change the path the name and what we dispatch right here now we can go to our auth reducer and perform a check of of this action which is signing now in our auto reducer all we need to do is to add this case right here let's simply say case sign in and a full column if i save that uh this should be automatically formatted and if it's not i can manually format it so this case sign in will also be similar to our sign up this is what will happen we will test the welcome message and then we'll record the user from the action.token and then we'll add the user to the state so you can see up sign-in and user-roaded all are doing are the same thing here or the functionality or the logic is the same now all we need to do is to dispatch our sign-in action creator from our front end so we will go to the orb folder and go to the sign-in component so from here i'll import everything we need to make use of our uh our signing action creator or to dispatch our signing action creator so first of all uh in this component we may need to use the state so i'll say use state i import use state from react and then we'll make use of use dispatch and use selector so i will import use dispatch and also use selector and all this will be coming from our react redux so use dispatch will help us to dispatch the signing action creator and then our user selector will help us to select a certain piece of state uh from our redux store and then the use state will help us to get our form values and we can then dispatch them now the other thing that we will need is the actual action creator so we can also import it here which is sign in and this will be coming from our old actions one level up another level up i access the store i access actions and then all actions so we have imported everything we need and we just need to make use of them so inside our sign-in component before our return statement uh we can include the default state right here so i'll say const we have credits and set credits so set credits will simply update our credit state and then this will be equal to use state i invoke it and pass some default state for our sign-in we expect a user to have an email so we can default it to an empty string and we also expect the user to have a password so i default it to an empty string now we can update our credits dot email and credits credits.password from our form when we type something in our form so right here first of all we will have a value prop which will be equal to um credits.email and then to update this value we will have an unchanged event so this will be equal to right here we pass an arrow function which will accept event and then um we can make use of set credits to update the credits so we'll say set credits i invoke it and then in here i'll spread the creds using the spread operator and then all we need to update is the email which will now be equal to e dot target and dot value okay i think this is correct so we need to do the same for our password i'll just copy this and paste it right here so this will be creds dot password and then for our set grades we'll accept an event spread the credits but this time we'll only update the password so now we are correctly updating the various for email and password and [Music] when we submit the form we will fire an on submit event right here i'll say on submit which will be equal to a helper method i'll call it under submit and now we can create this helper method i think i messed up something oh yeah it's okay if i save that i think it should be automatically formatted so we have an on submit under submit and we can create this under submit just before our return statement so right here i'll say const under submit which will be equal to an arrow function it will accept an event and we can prevent the default action for submitting a form so e dot prevent default this will prevent the page from refreshing uh whenever we submit the form uh just like that and i invoke it e dot prevent our default and then right here is where we can dispatch our action creator when we are submitting the form and we need to uh load the user dispatch hook so i'll say const dispatch will be equal to use dispatch and i make sure that i invoke that so right here i can simply say um dispatch i invoke it i call signing and i invoke it and pass the credits so this grades is this one which will have our values from the steps and then after that i simply want to clear the form various because our form values depends on the value of the state so if we clear the state we simply create the form values so right here i'll say set grades i invoke it and pass the email to be an empty array i also pass password to be an empty array okay now at this point we should successfully login the user but i also want to redirect the user to the home page in case uh an auth id exists like we did with our signup form so what i'll do is that i'll load the other state right here so i'll say const path will be equal to use selector we had imported user selector area from react redux i invoke user selector so what we get here is the state and we will directly return state dot auth now we have the auth and all we need is to perform a check so right here i'll say if of dot underscore id all we need to do is to return the redirect component so right here i'll say redirect and then we have a tool which is prop and we pass this uh path which is the home page where we have the list of our to do's and then now we can cross our redirect component and yeah this way also make sure that it was not added here i saw that uh that behavior okay you can see it was added here but we don't want it here i saw this behavior when working with our sign up so make sure it's not there and we need to import this redirect component from react router dom so at the very top let's import redirect and this will be coming from react router dome i just like that so right now we should be able to log in and redirect the user to the home page and i think we can also uh log off to the console maybe what we can do so that we also see the application state is to come to our uh gs component and log the state the console from here or rather from our navbar because the navbar is in every component like it's a shared component that's what i meant i think from here uh we can import use selector so that we also see our application state use selector okay and this will be from react redux react redux now we can make use of use selector right here or i will do is that i'll say count const state will be equal to use selector and i invoke this what we get is the state and we directly turn this state oops this is so bad now state we directly turn the state and we can lock this state to the console console.log state so at this point now we should also be able to see our application state in any component because our navbar is uh kinda shared now i run the application and we can test whether everything works so at the moment we don't have any um token at our storage so let's go to sign in and uh try to sign in the user so i'll search out two at gmail.com i'm not sure why they remember the password but let's try i'll click sign in and there we go we are successfully being redirected to the our to-do homepage and then we have welcome message and a token was added at our local storage so if we go to console right here we log the state to the console so we can see we have the state and when we check our auth state we have the email we have the name token and an id if i try to go to sign up i can't because i am logged in if i try to go to sign in i can't because i am logged in so we are successfully signing up a user signing in a user and also loading a user from the application state so loading a user is important because now when i refresh the page because we already have a token at our local storage we will still be signed in okay so yeah that's perfect now in the next section we'll see how we can sign out a user in this section i want us to handle sign out and if i come to the navbar component where we have our sign out button i can see that we had uh started to implement our the synod functionality so just right here while we have our sign out button we had added an encrypt event where if you click that button this underside of method is called and then in the senate method this is where we will dispatch an action creator for sending out a user and then right here we push the user to the sign-in route so to complete this functionality we can import use dispatch and also an action creator from our actions so we haven't created the action creator yet but uh since we know where it will be we can still import it and uh right here i'll say use dispatch and then right here we can make an import of our action creator and note that we haven't created this action creator yet but we will call it sign out and it will be coming from our actions so i go to desktop i access the actions and then i access the auth actions just like that and then we can uh initialize this dispatch right here so i'll say const dispatch will be equal to use dispatch i invoke that and then right here is where we will dispatch our action creator so this part i invoke it and then sign out i also invoke this and this time round we are not passing any parameter to our sign out action creator so let's go ahead and create this sign out action creator so i'll go to the actions and then we can create it at the bottom here so i'll create the sign out action creator export const sign out this will be an arrow function and then we return a function with the help of redux dunk and this function will have access to dispatch so that we can dispatch our actions and then uh in here we can dispatch an action of type sign out so this is all we need to do in this particular action creator all we are dispatching is an action of type sign out and this is it this is all we need to do for our sign out action creator it's a an arrow function which have access to this patch and then we dispatch an action of type sign out now we can go to our user where the magic of sending out a user will happen so after our case here now we will include a new case because this is now a different implementation i'll say case sign out so this is supposed to be underscore sign out and then a full colon and below here to sign out a user uh the first thing that we need to do is to remove the token from the rocker storage so right here i'll simply say local storage dot remove item and then i pass in the key for our item which is token so this will remove that token from the local storage and then we can post a message so all i'll do is that i'll copy this one and paste it here but we can change the message to goodbye because now you are logging out we position it at the bottom right and then after this we need to clear our state okay so in our state we need to set everything to null even in the token itself so all i'll do is that i'll say return an object which will have these properties so it will have a talk a name email id i'll copy that to make my work easier paste it here and the token will also be null now that we have removed it from the rocker storage so i'll save that and it will be properly formatted so yeah this is it this is where now we are signing out a user when we click the button from our navbar uh we will dispatch this action creator sign out and then this uh sign out will dispatch an action of type uh sign out and then this uh action we can check it here where we remove the the token from the local storage we toast a message and we clear the state so this this way the user should be successfully send out now i want to note out that since we are not performing a massive functionality here we can directly dispatch an action just in our navbar but just follow our our trend where we create action critters right here and then we use all the reducer to update the state we can do it this way for consistency now let's test the application and see whether our sign up functionality works so now currently we are logged in if i expand the state here you will see we have a token at our state and email name and id and when i check the application here we also have a token at our local storage now let's see if our sign up functionality works so i'll click sign out and you'll see that this token have been removed from local storage and when i come to the state so i'll come to the console which is here i expand this now you'll see that our off we are creating the state then the id token name email and we are redirected to the sign-in component so now now we can sign up we can sign in and when we come to our to-do up right here we can also be able to access our to-do's at the moment but we'll perform condition rendering later on and also redirecting the users if they are not send in but in the next section i want us to protect our api endpoints since now we have authentication such that only the logged in users can be able to uh delete or to do add a new to do and perform all those actions so right here right now i can add a new to do even if i am not logged in okay and uh that tool is appearing here i can mark and to do as done i can edit a to-do and i want this functionality to only remain to authenticated users so in the next section we'll protect our api endpoints so that only authenticated users can perform these actions and then we'll perform conditional rendering where we can hide some buttons here show the correct name of the logged in user and also make sure that we can't access our to-do's if we are not logged in okay in this section we are going to protect our api endpoints and we had created this middleware function at our backend which will help us to check whether our user requests have a valid token and if the token is valid then we'll go ahead and allow the user to access our todos api endpoint so how this function works is that it expect our request to have a header and at our header we are expected to have a key called x of token which will contain our jwt token and then if the token does not exist we return are not authorized to the user and if the token exists then we will verify the token using jwt verify where we pass the token here and also the secret key from our environment variable as the second parameter and what we get back is the decoded or the payload of that token and it will contain properties of our user that is the username the id and also the email so we add the user to our to our request so that now we can access this user from our to-do's apis and we can perform for the authorization so to start with we are going to create a function which will allow us to set this x of token together with average token of the logged in user so i'll go back to my front-end folder here and then insert the api folder we will access this index.js file right here we are exporting a url which targets our api endpoints and we'll also export a function which will help us to set the headers of our request so right here i'll say export accounts set headers and this will be an arrow function and then right here i'll say const header i will be equal to an object and inside this object and now we can set the headers with the small cup so this is a property inside this object called headers i use a full colon and then we can set a key and a value the key will be this one x of token i'll just copy that and then paste it here i use a full colon and then the key it will be our token and we'll get this odd token from the local storage so i'll say local storage dot get item and inside here we can pass the key of the item we are getting which is token so now uh when we call this function we should return this header which will contain our x of token and the x of token will contain a token from our local storage so right here we need to have a return statement and i'll simply say header now we can access this set headers from our to do actions where we are performing requests and set the necessary headers so right here we will import url from the api and also we will import set headers and when performing each request to our to lose api we'll need to pass this set headers function and it will set our headers to contain our x of token so to start with we can start with the get to those action creator this is where we are accessing the api endpoint as the first parameter and then the second parameter we will call set headers i invoke that and now this will set our headers to be exactly uh this one an object which have a property called headers and then inside that property we have another property which is a key which contains our token so just to mention you can pass this object directory to our uh to our get uh to our get method here as the second parameter but for simplicity we are using a function so that we can call this function from uh each of our from each of our requests to avoid uh this repetition okay so we'll go ahead and set head us for our ad to do so right here i can include a comma and we set the headers as the third parameter i invoke this one so for adding a new to do we are expected to have a url and then the body of the request and then this is that parameter where we are supposed to set our headers for our get we only have two parameters the error and then uh the second parameter is our headers we don't have uh a body of the request right here now for adding a new to do we can continue and add an order when adding a new to do uh so that this is now complete such that when we add a new to do we also get to know the other of that to do and also the uid of the person who created that to do so what i'll do is that i'll use an object here and then i'll spread the properties of new to do and the second parameter here will be order and the other one will be uid and we can get this directory from our state so we have access to get state and before we perform access dot post we can get our order and also the uid so right here i'll say const other will be equal to get state i invoke this we say dot off dot name so remember remember in our state we have the earth a state and also the to do state now we are getting the name of the other and then we can also get the uid of the order so i'll set the uid to be equal to get state i invoke this and then we say dot off dot underscore id and this is now the user id and we attach the other and the uid to our to-do so that now it will have the to-do properties and also the person who created that to do and we are also setting the the headers so that we send the token at our back end now let's go ahead to our update to do so right here we will have the url and then we will have the body of the request and now we can have the headers of the request by simply saying set headers i invoke that and then we can go to our territe or rather check to do's so this is supposed to have uh the first parameter is the url and then the second parameter is supposed to be the body of the request but since uh we are not us sending anything to the body so this is just an empty object a sub placeholder and then the third parameter is set headers and we invoke it or to set our headers and lastly we have delete which will have the first parameter is the url and the second parameter is the headers of the request so we'll just invoke our set headers function now for each of our uh to those requests we are sending a headers to the backend and when we receive this headers uh which is this one it will have this key x of the token and we will perform a check whether this x or token exists if it's null i will send back not authorized else i will perform some verification here and add a user to our request okay so in our request we will have user and we can access this user from our to those apis so i'll go to the produce api right here and we need to uh uncomment this one so how we are going to protect our routes is passing this middleware function so we are getting this is the middleware function this one where we are checking whether we have avoided token so we'll send this one as the second parameter after our path we include earth and then a comma and then the next in our middleware function this one here i will pass functionality to our uh async function here which will get our to loose from the back end so when we pass this off the user must be authenticated in order to get the to-do's so if there is if the user is not authenticated we will either get uh not authorized or inverted token from our middleware function okay so uh from our todos api we should pass this out as the second parameter for each of these requests but for further authorization we can make it in such a way that a user only get the to-do's that he or she added so we can perform a filter since in our odd here uh it gave us access to the user via our request so what we can do is to filter our to-do's just like this so i'll say const filtered to those uh will be equal to we take this to this array which is the entire array so i'll say to do's dot filter i invoke this and in here we will get each to do at a time and we will perform a check so we will say if to do dot uid is equal to our request dot user dot underscore id then we return that to do if to do dot u id is equal to request dot user dot underscore id we return that to do and it will be added in our filtered produce array so remember this to do dot u id is coming because we added a uid in how to do actions just right here this is where we added the uid and then for a request dot user dot i is coming from our middleware function where we verified the user and added the user to our request okay so now we can do request.user and then access a property of the user which is dot underscore id so this is what is happening there and then right here instead of sending all the to-do's to the user we can send only the filtered to those so right here i'll say filtered to those so now a user can only get to do's that he or she added and not other users to do so okay okay now this is for get let's go ahead to our post so right here we need to pass up as the second parameter and this is our middleware function which checks whether our headers have a varied odd token and uh right here we are adding the other the uid uh at our new to-do so you are getting it from request.body and this is all we need to do for adding on you to do we only need to pass up we don't need to do anything else so we can go to the next one which is editing a to-do so we need to pass all right here and then after we perform this check whether to do exist or not uh we can also perform a check uh whether these are varied user or not avoid user who is making the request okay so we want users to only edit to do's that are they are dead in the database and not other people's to do's so what i'll say is that if are to do our dot u id so right here you have checked that to do is uh exists if it exists then we can say to do dot u id if to do dot u id uh is not equal to we have a user in our request is not equal to request dot user dot underscore id then what we will do is that we will return we will say res dot status and the status code for this one will be 4 1 so right here i'll say for one which means are not authorized and then we can send this message dot send i invoke it and i'll say how to do update field [Music] and at the end here maybe i can minimize this one i can also tell them uh it's because they are not authorized to edit that to do so not authorized and maybe i can include three dots i'll save this at property format this card yeah that way so uh this is for our edit uh we fetch the to do right here if that do exist we'll proceed to this sparring here to do dot u id if it's not equal to request dot user dot underscore id now this is the person making the request or the currently logged in user then we'll tell uh the user that uh oops to do update field are not authorized and the code is for one and then now we can do the same for our delete actually i think i'll just copy this and then for we this was for put request okay we also have a patch request i'll include auth which is our middleware function for checking the headers then we check if the to do exist if the to do exist then we'll perform this check the same as the the above okay so under the message you will change maybe to do check stroke uncheck failed not authorized and then we can go to our delete i pass odd here we check if the to do exists if it exists then we also perform this check and we will change the message to do deletion field not authorized okay so now uh we are correctly uh protecting these routes first of all if you are not authenticated you want to be able to delete a to do then if you are not authorized director to do you would be able to actually edit delete it and we are doing this for these other api endpoints for our to do and now the only thing that remains is to test whether our application works okay just to take you through uh the thought process of what we have done uh first of all we we started by creating asset headers function which includes a key in our headers called x of token and we set the token to be from our local storage and then with every request we are setting the headers for each of this request so when we make a request what will happen is that uh for example if we are getting a to-do i will get to this path and then this is the function that will be uh executed first so we will go to odd.js check whether our request have a header and inside the header we have x of token if the token does not exist will tell the user uh oops we are not authorized else we will verify the token and include a user to our request else we'll say invalid token so if this succeeds we pass functionality to the next middleware function which is our function here right here so when we get to this point now in our request we will have a user and we can do something like request dot user dot underscore id and we can do a filter for this to do where we get to do which we ourselves added and not other people's to do and then for post we only need to check whether the user is authenticated to post a new to do but we'll also add an author and a uid to that to do and then for put uh we check whether the user is authenticated and then we also check whether they are the one who created that particular to do so that they can actually edit it the same happens for patch and the same happens for delete now there is one last thing that we need to do we need to go to our produce folder here and then add to do component and when we update a to do we need to include all the properties that are required we need to include a varied over uh the currency login user and also a uid so i replace this line with these two lines okay we have the order as to do dot author and uid as to do dot u id and this will properly update to do now we can go ahead and test if everything works so i'll go back to the browser here and uh at the moment you'll see that we can't get our to-do's because we are not logged in if i try to refresh this one [Music] you will see that we are still getting an error and if i expand this you see that at our auth everything is null and when i check the application here we don't have a token okay so if we try to add a new to do when we don't have a token and submit you'll see that we are getting an inverted token and we can't actually add to do so we are correctly uh protecting our api endpoints and to confirm this we can sign in as a user enter a varied password uh signing [Music] and once we are uh signed in we can now add a new to-do and you can see it was added here we can try to add another one and we can mark the to-do as done we can edit it and also we can be able to delete our to-do as long as we are logged in we can be able to perform all these actions okay so if i sign out will be redirected to the sign-in component if i go to that to do right here uh for some reason we still have this in our state but when we try to mark it as done you can see inverted token if we try to edit it we can't be able to delete to edit it if i try to add to that it also we can't delete and if i refresh this page you'll see that we can't get uh that to do from the back end so uh right now we are correctly uh protecting our api endpoints and in the next video i want us to perform some conditional rendering such that if you are not logged in you cannot access our home page so you won't be able to see a sign-in form you want to be able to see the to-do's and also you won't be able to see some of this button so if you are not logged in you'll only see sign in and sign up you won't see sign out else if you are logged in you'll see sign out and on and you'll not see sign in and sign up and also will update the name right here in this section i want us to perform some conditional rendering and we'll go to the to do jsx component and this was the parent component for our ad to do component and for our list to this component so we don't want to see this component if we are not logged in okay so we must be logged in for us to see our to-dos so i'll import a user selector from react redux and also the redirect component from our reactor dome so right here i will say import redirect and this is from react router dome and then i'll import use dispatch uh not use dispatch use selector from react redux and then we can use our redirect and use selector to redirect a user so first thing we will do is to load our auth from state so right here i'll say const of will be equal to use selector i invoke this what we get is the state and we can return the all the state by saying state dot off and now before our return statement we can perform a check if uh we don't have an auth dot underscore id we should redirect the user to the sign-in page okay so right here i'll say return the direct component we use the two plop and we set it to be equal to stroke signing and then right here i cross our direct and this should not be here so just like that we are getting uh odd from the state if there is no an id in our earth that means that the you the user has not logged in and therefore we redirect them to the sign-in page else our components here will be returned so now let's go to the navbar component and we want to hide some things depending on whether a user is logged in or not so right here i will load a user from the state i'll just duplicate this one and then instead of returning the state here i return state dot off and i can get right here or the user and then i can use this auth to perform some conditional rendering depending on whether a user is logged in or not so we want to display uh this message logged in as that user and also we want to display sign out if the user is logged in so we can display the correct name here by using the curry brackets and then using auth dot name so this is the name of the currently logged in user and then uh i can use this curry brackets and perform a check if of dot underscore id exists that means that the user is logged in and therefore we should display these two this message and the sign out button so i'll use a question mark and this brackets and include these two components in here else uh we should display the sign in and the sign up buttons so right here i should use a full colon and then add brackets and display uh these two buttons so i'll cut that and include it here so this should be wrapped in a single element so i'll make use of react fragments which is an opening and a closing tag and move them in those two [Music] elements [Music] and the same should happen for these ones so where we are performing a check bracket we should have these two so these are just react fragments and then we move the typography and the synod button in our react fragment [Music] so i'll save this at correctly format it and this is what is happening if we have an id it means that we are logged in and therefore will display this message and then the sign up button else will display the sign-in and the sign up button now we can test our application so now our application has loaded and uh you can see we are not seeing the sign out button and the message that we are seeing here so we can try and login we enter a password i sign in and once we are logged in you can see we are displaying the name and also the sign up button but we can see the sign in and the sign up button so if i try to sign out and try to access our to-do's here we can't because we are already logged out so at this point i think we have achieved our goal of creating a to-do app with authentication and performing all the cred operations in our application and in the next video we'll see how we can deploy our application so that you can access it online you
Info
Channel: Chaoo Charles
Views: 4,369
Rating: 4.949367 out of 5
Keywords: chaoo charles, chaoocharles, chaoo, charles, react tutorial for beginners, react hooks, redux hooks, mern stack tutorial, software development, software engineer, useState hook, useEffect hook, useDispatch hook, useSelector hook, axios, auth react redux, auth react, auth react js, auth jwt, auth jwt token, auth react jwt redux, auth react jwt
Id: aMFClmsA9Xw
Channel Id: undefined
Length: 112min 56sec (6776 seconds)
Published: Sun Apr 18 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.