MERN Auth - Login with Email (JWT) + Google OAuth Authentication | React, Node, Express, MongoDB

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Code is pretty clean I enjoyed that! Maybe you mentioned it in the video and it’s just for learning purposes but you really shouldn’t be storing all that sensitive information (email, password, token) in local storage right?

πŸ‘οΈŽ︎ 7 πŸ‘€οΈŽ︎ u/DasBeasto πŸ“…οΈŽ︎ Jan 15 2021 πŸ—«︎ replies

Let me know what you'd like to see next :)

πŸ‘οΈŽ︎ 2 πŸ‘€οΈŽ︎ u/HolidayInternet πŸ“…οΈŽ︎ Jan 15 2021 πŸ—«︎ replies

Great! I'm already looking forward to the next part. When are you planning to do it?

πŸ‘οΈŽ︎ 1 πŸ‘€οΈŽ︎ u/uke34 πŸ“…οΈŽ︎ Jan 15 2021 πŸ—«︎ replies
Captions
hello everyone and welcome to a project video where we built a full stack marin application our memories project in previous videos you'll learn how to build a full stack man project in this video we're going to add authentication auth is a complex process it means allowing users to log in and register today you're going to learn it completely email login using json web token oauth google login and much more if you haven't watched the first two parts they're going to be linked in the description make sure to watch them first and then come back this video is special because it can be watched as a standalone video that features you authentication so if you feel that you already know the basics and you want to learn the authentication only you are in the right place however i'd still strongly encourage you to watch the first two parts because then you'll have a much stronger understanding of the project we're building as i mentioned before i initially planned on putting this as a paid course but i later decided to release it completely free for you guys here on youtube so to support this video leave a like comment and subscribe it shouldn't take more than a few seconds and i really appreciate it on another note some of you in the comments requested me to add some extra features to this app things like pagination or even a live chat feature if you'd like me to create a fourth part of this series where i add one of the features you requested make sure to like and comment what would you like to see next if this video reaches 5 000 likes we are recording part 4. with that said let's jump into the demo of what you're going to learn how to build today we can start by logging out because that's the only thing we had before before we only had the memories and that was it now as you can see we added the sign in button on top right and also we masked the form so right now it's not visible if you're not logged in also as you can notice you cannot like something if you're not logged in so let's click sign in and see what do we have in here you have a complete form to sign in email and password in here you can sign in with that or if you don't have an account you can go ahead here and create an account you need to type in your first and last name email and password and that's it you're simply going to be signed up and then you can log in with that account now just to be quick let me show you something simpler just click here google sign in we are also going to implement that with one click you'll be able to log in with your google account and take a look at that you're in there it automatically found out my name also my image right here and there we go with that you can like other people's posts and notice this you can also delete your own post and then you also can create new posts yourself one more really cool feature is that we implemented only one like per person considering that we now have the accounts it's easy to simply keep an account who likes things before you were able to like indefinitely but now you can only leave one like per post as you can see we've added quite a few complex features such as login and registration using json web token so that's also something we're going to learn today also oauth using google and finally we are also using local storage so if you come back to this website or refresh this is going to be saved in the local storage so once you come back you're still logged in if the token hasn't expired quite a lot of interesting stuff coming up so let's dive right in [Music] before we start with coding i would just like us to be on the same page on where we are with the project down below i'm going to put the link to this project marin memories github repository in here you have everything that you need if you get stuck you can find the correct code right here also i've created two different branches part 1 and 2 and separate part 3. we're going to start with part 1 and 2 today that's going to be everything that we've done so far and then the part 3 contains the full authentication code so if you're just tuning in and if you haven't watched the part 1 and two you can click here part one and two and simply fork the repository as you can see on the top right you need to fork it forking a repository simply means that it's going to show on your own profile and then you can clone it and use it and if you guys followed part one and two in that case you'll most likely have your own repository but if you don't already definitely make sure to clone it and again i highly advise you to watch them because there are gonna be a lot of parts that are gonna be referenced from the part one and 2. right now i also want to show you an amazing tool that we'll be using today it's called zeet the link is going to be down in the description zit is going to allow us to deploy our database our mongodb database our frontend part with react and also our backend part so far to deploy these things you needed like three or four different tools mongodb atlas for the database then you needed something like netlife for the frontend part and finally you needed something like heroku for the back end and all of these tools can be unreliable and they don't work well together so it can happen that one of the services doesn't communicate with the other with zit you do everything in one application it's all together so make sure to click this login button on top right and you simply log in with your github account you can simply do that right now because we'll definitely be using this later and for people who haven't been watching the first two parts is that you need to head to cloud.mongodb.com and then in there you need to create your cluster now for the cluster setup you can go into database access and create a new database user and give him all permissions finally in the network access you can click add ip address and click add current ip address with that if you go back to clusters you can go to connect connect your application and now you have this connection url that you can copy make sure to exchange the username and password right here amazing again if you're having trouble with this i think this is mentioned in the first part of the video somewhere at the start so definitely make sure to watch through that now we are ready to dive with coding so what i'm going to do to make sure we're on the same page is i'm going to simply clone the part 1 and 2 branch of the project mirror memories and that's where we're going to start from to do that make sure to open a new visual studio code window head under view and finally terminal inside of here you can simply say git clone and paste that link make sure that you have git downloaded and installed you can simply google something like git download and that is going to be it once you clone it you can cd into project man memories and you need to open this inside of your visual studio code you can simply type code dot and this is going to open it in a new visual studio code window this command is not going to always work so if it doesn't work for you make sure to find this folder inside of your file explorer and simply drag and drop it into your visual studio code window that way you'll have this opened and will be on the same page now we can prepare terminals so what i'm going to do is i'm going to split our terminal into half and i'm going to clear both our left side terminal is going to be for our client side or the react so we can say cd client now we are in there and what you can do there is we can first install something so i'm going to say mpm install and there we're going to install jwt decode and also we need to install react dash google dash login so these are the only two dependencies we'll be using in part three once you click that that's going to install all the necessary dependencies and also on the backend side we need to cd into server so cd server and now in there we can also write npm install and we can install b crypt js and also json web token great that's going to install all the necessary dependencies great that seems to be it so now if we go to our server you can see here we have those things installed and if we go right here you should be able to see that we have these two dependencies added just to make sure all of these are installed and up to date i'm just going to run mpm install without any dependencies one more time just to make sure that we have absolutely everything that we need okay there we go that is it so now if you clear both sides and you simply type mpm start it's going to start both sides and we should be able to see our application up and running and then we'll be ready to start with coding and there we go our application started if memories didn't show up for you try creating some or go to server and make sure that this connection url string is written correctly so you have to have your username here password here and then finally you need to have the name of the database at the end this can really be anything with that said we can close our terminals we can reopen them when we need them and now we can start implementing auth we can start on the front-end side we can first start adding on the navigation bar the items for the login and registration so once we click that we'll be redirected to a different form the form for login or register so let's do that first if we go back to our code you can head to client we can go to src components and then right inside of here we can create that nav bar if i remember correctly we also had a bit of a navbar before but we didn't have it as a separate component so if we go to app.js you can see that our nav navbar is here so we're going to divide that into a new component so inside of components we can create a new component it's going to be called nav bar and now we can create a file called navbar dot js and also styles dot js we're going to copy what we have so far in our app so right here and i'm going to create a rafc a react function component with exports and we're simply going to paste what we have so far okay that's great as you can see i'm using eslint so some of the things are going to get changed immediately but don't worry about that and finally we have to import some classes so in here we also need our app bar and typography so i'm going to go here and say import what do we need the app bar and typography from add material ui forward slash core and then finally we also need our classes so to do that i'm going to switch this back to the normal return function right there and what we need to say is const classes is equal to use styles of course right now we don't have the styles but we have to import them so again as we always do i'm going to give you all those styles right away right here you can simply copy and paste them they're going to be down in the description for absolutely all of the components now at the top of the file we can say import use styles from and that's going to be just dot slash styles a lot of you guys mentioned that you like these applications and that you like building everything out and even though you prefer that i simply copy and paste the styles for simplicity and time saving purposes you'd want to learn a bit more about material ui and how to style things with it so what do you say do you guys want me to make a separate material ui video where i'm going to teach you how to do everything material ui and also how to do the styles let me know in the comments down below okay with that said looks like we are missing one thing from our navbar and that is the link to the memories image so if you go back to the app you can see that we simply need to import it i'm going to copy it from here also i'm going to remove these things right there because we don't need them anymore and now in here we have to import that path now the pad is going to be just a bit different it is going to be data slash and then dot slash images memories png okay with this we haven't done anything special we just removed our navbar so to bring it back we have to go to the app.js and then in here we need to import that navbar if you simply start typing in visual studio code it's going to immediately import that for you so that's really handy i'm going to put it right there and that is going to be a self-closing component if it didn't import it for you just make sure to say import navbar dot slash components and then navbar navbar okay with that said if we go back you can see that we have everything you had so far so why did we even put it in a new component in the first place well now we're going to make it more complicated so we didn't want to clutter the app we want to have everything in its special components okay so what else do we need in this navbar well we're going to change it a bit so inside of here i'm going to create a new div that div is going to have a class name of classes dot brand container and we're going to put all of these things inside of it so now we have a div and we have a typography and image right there this typography is going to be of a component which is equal to link because it's going to be pointing to our home so we can say to and we can just say slash because it's going to be our main route and of course we have to import link from react router dom also i'm not sure if installed react router dom looks like i missed that so what we have to do is open our terminal one more time we have to close this from running by pressing control c and then y and you can simply say npm install react router dom yep we also need that because now we're gonna have a complete app where we're gonna route things so you can wait until that installs and we will simply restart the application by running npm start great now we have the react router installed as well and that's not going to be a problem okay that's going to be it for our typography and that's also going to be it for our image so moving below just below our div we can create a new component which is going to be called toolbar that toolbar is going to have a class name of classes dot toolbar and down below we're going to show some logic depending on if we have the user logged in or if you don't so right now i'm going to create just a mock user so we can say const user is equal to null later this can be filled with an object with a real user or maybe the user is not logged in so what we can do is we can do something like this if user exists right if user exists then we're going to show something right here and then we can use another ternary to say else show something else right here so we'll be showing something if a user is logged in and something different if a user is not logged in if the user is logged in we want to show his information so in here i'm going to create a div with a class name of classes dot profile in here we're gonna have an avatar out there is simply going to be a small circular image displaying how our user looks like or it's simply going to show a letter of their first name so we can say avatar classname is equal to classes.avatar or it's going to be classes.purple yep and then we have an alt tag alt is going to be equal to user.result.name and then it's also going to have an src so src can be equal to user dot result dot image url so later on when we actually get this user we want to display all of these informations finally if he doesn't have an image we want to show the first letter of his name and that is going to be user but we need to open a block of logic here user dot result dot name dot car at and simply call it and say zero so we want to get the first character that is it for the avatar now below we want to have a typography so we're going to say typography the class name is going to be equal to classes dot user name and variant is going to be equal to h6 inside of there we can simply open a new block of code and say user dot result dot name the last thing that we need to have is the button to log out so i'm going to create a new button the variant is going to be contained like this and a class name is going to be equal to classes dot log out we are also going to have a color and that color is going to be secondary we need to have an on click property but we're going to leave that empty for now and finally we have to write what the button is going to say and that is going to be simply log out great so this is the block of code we see if we are logged in if we are not we simply want to show the button to log in so let's create that button that is going to be button it's going to be a component which is equal to link and it's going to have a to property to forward slash auth so this one is actually going to redirect us to a different page where we're going to show the authentication it is going to have a variant of contained and a caller of primary what the button is going to say is simply going to be sign in so in here we can say sign in okay and now you can see we don't have a few components imported so that's going to be a toolbar and a button so right here we can import the toolbar and the button great so now if we save that let's see how does that look like okay we first got an error because we are using a link outside a router that means that we have to actually use our react router dom to make our app multi-page we make our react apps multi-page using react router dom so we can do that if you go back to the application and now instead of here we can import some of the things from react router dom these things are going to be browser router switch and also route from react router dom great now inside of here i would first like to move this thing into a new component because we'll be adding a lot of things to it we want to keep our app clean so i'm going to copy all of this with the grow and we want to create a new component so i'm going to create a new folder called home create a new file called home.js now that we have the home.js component in there we can also create an rafce and simply paste everything that includes this grow right here of course we'll have to import some components so i'm going to copy the imports from the app.js and paste it right here container grow and then grid you can also see that we are missing the posts and the form so let's import that import posts from dot slash it's going to be dot slash posts forward slash posts like this and then we also need a form so that's going to be import form from dot slash form forward slash form okay now we have the form as well and you can see that we're missing the current id and the set current id so how do we get that well if you think about it we can declare it right here and not have it in the app because because the app shouldn't be doing any major logic especially not with the posts posts are only contained in the home so we can actually use this dire logic and move it all the way to our home first let's delete this thing that we copied so inside of here we no longer have this what we have now is going to be a self-closing component which is simply going to say home okay with that said we can copy this entire part and we can paste it in the home component my eslint again turned this into an instant return but i'm going to bring it back and create a normal return just so i can put these things here so let me just space that out and as you can see now we have the current id and the set current id right there we have to import the use state use effect get posts and the use dispatch though so we can head to the app and we can mostly get all of the imports from here you can see import used dispatch from react redux so let's copy that then we need get posts we also need to import that so that's going to be around here but the pad is going to be different it's going to be dot slash and then one more time dot slash okay and the final thing is to import use state and use effect from react with that our component is filled and now in the app we can get rid of this extra logic there we go take a look at how many things we don't need right now to clutter our app we have everything in the home so let me let me remove these things we don't need that no need for any components right now and the only thing that we have is the navbar and the home and as you can see we have that and i think i removed the import from react router dom which we are going to need yep that is right here so i'm going to bring this back and now we can implement our react router so how can you do that well you have to wrap everything in the browser router so i'm going to do that right now browser router and then we have our container right there then we're going to have a switch statement right here so you can say switch and i see that i didn't name it properly so i'm going to rename it the switch right there and then inside of the switch you need to have a few routes so i'm going to create our first route that route is going to be self-closing tag and we're going to simply say path is equal to slash so this is our home route it needs to be exact and the component is going to be equal to home component we have to import it right there then below that we're going to add one new route this one is going to have a path of auth and the component is going to be called auth this component is not defined yet so we have to create it let's do that right now inside of our components i'm going to create a new component or rather a new folder called auth inside of that odd i'm going to create a new file called auth.js and also we're going to create styles.js for the odd file again i'm simply going to say rafc and by the way if you don't have that that is going to be a package uh let me take a look it's going to be es7 react redux draftql snippets so you can download that that's going to autofill the rafc for you okay and then in here for now i'm simply going to say auth that is going to be it okay and i'm using eslint and i don't want this to be changed on instant return because later on we will need something i'm just gonna say const state is equal to null here okay that way everything is going to be centered like this okay with that we now have to import this component and again if you simply type it and click right there it's going to be imported right for you okay so with that our routing should be done as you can see we have our nav bar it's not inside of the switch so that means it's going to be showing up always and then we have our switch which means switch between these two components either show the home or show the auth and of course we have to remove this home from the bottom because we are showing it right here okay now can we actually see this in the browser let's test it out and there we go everything is as it used to be but we made a few different components we created the one for the navbar and we created a home component with the form and all the posts now let's try clicking the sign in and see what happens and there we go we are routed to a completely different component that now says auth this is the place where we're going to implement the login and registration form that seems like a valid next step so let's do that next okay let's start creating the layout for our auth form inside of the auth.js we're gonna first import a few things and these are going to be again avatar button paper grid then we're going to need a typography and finally a container all of these are going to be imported from add material ui forward slash core while we're here we can also import the styles meaning use styles from dot slash styles and of course we have to create those so again linked in the description are going to be the styles for this specific file i don't want you to spend time on writing css i want you to focus on the important things which is in this case authentication okay with that said we can say const classes is equal to use styles and call it as a function now we can start creating the layout for our odd form and it's going to look like this first of all we're going to wrap everything inside of a container that container is going to have a component property which is going to be equal to a string of main it's also going to have a max width property which is going to be equal to xs down below we're going to wrap everything with a paper so we can say paper and that paper you're going to have a class name of classes dot paper and also an elevation of three this is simply going to make a white style div that looks like a paper and there we can have all the inputs inside of that now first thing inside of that is we're going to have an avatar and that avatar is going to have a class name of classes.avatar inside of there we're gonna have a lock icon so right inside of here you can create something like this lock outlined icon and that is going to be a self-closing tag that we have to import so at the top let's import that icon it's simply going to say import log outlined icon from and in this case it's not going to be add material ui core it's going to be add material ui for slash icons and then forward slash lock outlined there we go now that we have that we can continue with our form below the avatar we're going to have one typography this typography is going to be of a variant which is going to be h5 and it simply needs to say either sign up or sign in depending on what we want to do so right now i'm going to create once again a mock variable for now which is going to be called is sign up and we're going to leave that to false right now based on this variable we're going to change a lot of different things in the form so right now we can open a new logic block and we can say if is sign up then we want to show something like a string of sign up otherwise we want to show sign in now below that we're finally starting with our form our form is going to have a class name of classes dot form and it's also going to have an on submit right now we don't have an ounce of bit but we could as well create it so i'm going to say on submit the function we're going to call is going to be called handle submit so just right here you can create a const handle submit function there we go for now we're going to leave it blank now inside of our form we're going to have a grid that grid is going to be of a type container and it's going to have a spacing equal to 2. inside of here we can show all of our inputs so let's first start with the first name and the last name remember we only have the first name and the last name if we are signing up if you're already signed in we don't need that so we can open a new blog and we can say if is sign up then we could use the ternary but we can also use the end end operator so we can say is sign up only if it is sign up then show something and in this case we're going to show an empty react fragment and then inside of there we're going to show two different inputs so these are going to be text field elements we can say text field like that and we're going to have a few different things there we need to have a name so name is going to be equal to first name then we also need a label which is going to be equal to first name we need a handle change method so i'm going to say handle change here we can go ahead and create that handle change right now pendle change is going to simply be equal to handle change so let's create an arrow function here const handle change is going to be equal to an arrow function okay what else do we need on our input we need also the auto focus because this is going to be the first element we want to focus on and then we can say xs is equal to 6 and we'll need a lot more things i'm going to explain why this is going to be different in just a second so this is going to be a self-closing tag there we go now of course we're going to have one more for the last name we have to change all of these things then we're going to have multiple more text fields for passwords for confirming passwords for email and all of these are going to be kind of different but in most cases they are going to stay the same so we don't want to have the inputs that have like 10 different props what you want to do when you have most of the same components most of the components that look and behave the same is you want to create a new custom component which is going to generalize the logic that way you don't have to write everything for each one of them you can simply create a one that has all the things and then only specify the things that change it might be complicated but let me show you what i mean this is a really really good practice in react so inside of here instead of our auth i'm going to create a new file called input.js that input is going to be an rafce a simple component and we're going to import a few things from material ui these things are going to be text field we're going to import a grid we're going to import an input adornment and we're also going to import the icon button from react material ui and that's going to be core okay great and i also forgot like in here we don't only need a text field we need to wrap each text field with a grid so it would look something like this and then each grid would have a property of xs is equal to 6 and then md is equal to 12 or something like that so you can see here we have this grid once but then again you need to have it for each new text field and you can see it it kind of adds a lot of code it makes it unclean a lot of repetitive code at least you can see so now we want to change that we want to make a generalized input field so to do that we can create one grid right there and all of our inputs are going to have that grid that's going to save us the trouble of writing this multiple times this grid is going to be of type item it is going to have the property of xs equal to 12 but what if we want some inputs to take only half the width then we can do something like sm is equal to 6 but now all of them are going to take half the width so we have to have a special prop we can name it something like half and then if half is true we want this to be 6 otherwise we want this to be 12. so see how we can make it dynamic okay now inside of there we want to have a text field text field belongs to material ui and it is going to be a self-closing tag i'm going to expand it on multiple rows so we can add our props inside of there each text field needs to have a name so i'm going to say name is equal to name right there because name needs to be dynamic as you can see right now we don't have a name so all of these things we have to import as props so inside of here i'm going to add a name then each text field needs to have an unchanged property so i'm going to say on change is equal to handle change then we have a variant that is equal to outline this is the same for absolutely all text fields so we don't have to change that another thing that is the same for all text fields is going to be required we don't have to send that as a prop that is always going to stay the same all of them are going to have the property of full width then for the label we have to change that so i'm going to say label is equal to label and we're going to pass that as a prop finally auto focus is going to be equal to autofocus and type is going to be equal to type and one final thing that's going to be happening only on one input is going to be called input props like this with a capital i capital props that is simply an icon that we're showing on the right side of the input if we want to click it and that's going to be for show password you know that field when you have a password then you're not sure what you typed in you want to click that and then it's going to show it to you so we can open a new block and then we can say if name is equal to password like this then we want to show a block of code so you can open this and say end adornment is equal to and in here you can use the input adornment that's going to be a component the position is going to be set to end so position set to end and all that we need is going to be an icon button that icon button is going to have an onclick property which is going to be equal to handle show password and in there we're going to show if type is equal to password so if type triple equal to password then we're going to show an icon that says visibility okay a self-closing tag otherwise we're gonna have an icon that says visibility off and it's also going to be a self-closing tag we can now this is going to be the end adornment but if we don't have that we can simply say null don't show anything and if you know react or javascript you know that when we have a ternary operator with the second value being null what you can do is simply change this to end end and then you don't have to provide that null right there great so if you save that you'll see that we're missing quite a few things that we need to import here and this is actually good because this means that we are taking all of the things that we need in here for this special input and we are importing them right here and not in our auth because in that way we're cluttering our odd component which by itself is already be complicated so let's import those icons right there import visibility from add material ui icons forward slash visibility i'm going to copy that line and the second line is simply going to say visibility off great now all of the other things that we need like handle change label autofocus we're importing from here so let's do that name handle change we need a label we need a half then we need the auto focus the type and finally the handle show password with that our custom input is done you can see we are exporting it as the input finally we can import it right here import input from dot slash input great now instead of typing all of this we can remove the grids completely we can remove that this as well and we're going to rename this to input instead of a text field and now as you can see we are passing only the props that we need name is equal to first name label is equal to first name we're passing the handle change method and everything else that we need in this case i think we simply specify the property half so we don't need to say the xs is equal to 6 we can simply say half and that is going to make it six and for the second one we don't need the auto focus as well because we have that and we can say half as you can see this makes our inputs a lot slimmer we don't need to have something like let me take a look something like variant outline for each one required for each one full width for each one and all of these things we simply specify what we need and now we can continue with all the inputs that we have both in the login and the register form so let's create them we have a new input this one is going to have the name of email a label of email address and a handle change which is going to be equal to handle change finally in this case we need to have a type and the type is going to be equal to email below that one we're going to create one new input also a self-closing tag this one is going to have a name is equal to password it's also going to have a label which is going to be equal to password and it's going to have you guessed it a handle change equal to a handle change the type is going to be of course password but what if we want to click that button which means show password in that case we have to change this from password to simply text that means that we need to have some kind of variable that's going to manage our show password and that is going to be a state so we can do that right now we can import react as well as the use state hook at the top and now we can create that show password field so right here i'm going to say const make a new state and we're going to say show password and set show password so this is going to be our state and that's going to be equal to use state and at the start it is going to be set to false okay so now based on this state we can say if right here i'm going to delete this if show password is true then show text otherwise show password okay and finally the final prop that we have to pass is handle show password is going to be equal to handle show password and what is that well that is going to be one function that is going to handle the show password obviously and the handle show password is going to be an error function handle show password that is simply going to toggle the state of the password so we can say like this set show password and then in here we need a prep state so previous state whenever you're changing the state using the old state you have to create a callback function and then you have to get the prev show password and then what we want to do in here is simply say if the previous show password is something we want to say false and then previous show password that means that we're toggling it so if it's on turn it off if it's off turn it on and we're passing that over as a prop handle show password okay there we go now our input for the password is done below that we want to have one for the confirmation and again the password confirm field is going to show only if you're on the sign up form not on the sign in so i'm going to say if is sign up then end end then we show this input field this input is going to have a name of confirm password it's going to have a label of something like repeat password and it's going to have a handle change again be equal to handle change finally the type of this one is going to be password okay we have all of the input fields that we need right now finally we need a submit button so right below the grid i'm going to create a button and that button is going to be of a type is equal to submit so we're going to submit the form on this button it's going to have a full width property also a variant of contained and a color of primary as well as the class name of classes dot submit and now inside of that button we want to say either sign in or sign up so we can again use that property is sign up if it is sign up we're gonna show sign up otherwise we're gonna show sign in great so now it would make sense to take a look what do we have let's go back to the browser and see if we have the auth right here and there we go take a look at that we have our sign in form but right now there is no way for us to switch between the sign in and the sign up so how can we do that well right now we can just change this dummy variable to true and that should show us our sign up now we have the sign up with the first name last name email and password repeat passwords as well and the button says sign up this is extremely good because what beginners in react would do is they would create two different components for the sign up and the sign in they would copy all of this code right here and create two different components what we did is we just created one variable called is sign up and then based on the change of that variable we changed it from sign up the title we added or deleted some fields and we also changed the title of the button you can see in react you have to think reactively one last thing that we could do is we could make a button that's going to allow us to switch from the sign up and the sign in so let's do that right now below our button still inside of the form we're going to have another grid this grid is going to be of a type container and it's going to have a justify property which is going to say a string of flex end inside of there i'm going to create a grid this grid is going to be of a type item and then inside of that grid we're going to have a button and that button is going to have an on click property and on click we're going to call the function called switch mode so that switch mode again is just a function which we're going to declare right there const switch mode it's going to be an arrow function and then in here we're going to switch the mode from the sign up to sign in now what is our button going to say again it's going to be different if we're logged in or not so i'm going to again open this say is sign up if we are on the sign up we're going to say already have an account question mark sign in otherwise we're gonna say something like don't have an account question mark sign up okay let's save that and see how does it look like there we go you can see that we have this button right there but right now it's not doing anything so what do we have to do to actually make this is sign up switchable think about this for a second try implementing this yourself and then once you've figured it out or once you're stuck come back to this video and i'm going to show you how to do it what we have to do to make this work in react fashion is make a new state field i'm going to take this is signup variable and i'm going to turn it into a state field so i'm going to say const is sign up and set is sign up that is going to be equal to use state and at the start that can be false now we can remove this everything is still going to function but now we have access to this set is sign up and now we can use that inside of our switch mode function so right inside of here we can say set is sign up and what we simply need to do is do the same thing that we did right here for the password since we are using the previous state to manage a new one we have to get a callback function and say prev is sign up and then in here simply say not prev is sign up that's going to switch it on and off like a switch also i want to reset the show password if i switch the mode so i'm going to say right here handle show password and i'm going to pass the value of false let's save it and see if it works we are on the sign in i click it we are on the sign up there we go this works as expected now we have a great looking form as you can see we can go back in here we have all of the posts we can head to the sign in and there we go in here we have the sign in and the sign up form which both look amazing now the login and register using these fields the first name last name email and all of that is going to take a bit longer so what i would want to do first is implement the google login button that way we can first handle the authentication with google and then we'll be able to do everything else that's better because if we first implement google that way we'll still have everything functioning as normal and then later on we'll be able to add everything else including these fields let's add the google sign-in button right here above our current one to do that we'll have to import one thing and that thing is called google login so right below our material ui imports in here we can say import google login from and that is going to be react google login we install that package at the start of this video okay and now we have to use that google login how do we use it well it's going to be a simple button so right here above our current one i'm going to call that google login as a component and it is going to be a self-closing component and here's a hint for you whenever you're importing something and that something starts with a capital letter most likely it's going to be a component inside of here you have to have your own client google id so this is something that we're going to add as soon as we're done with creating the layout for this so i'm going to say google id we have to put that right there then below we have render render means how are we going to show our button what is it going to look like so in here you get something known as render props and this is a callback function so inside of here you can create a callback function it's not going to have curly braces it's going to be just an instant return and then inside of there we're going to put a normal material ui button that button is going to have a class name of classes dot google button it's going to have a color of primary also it's going to be a full width button and it's going to have an on click listener on click we're going to call the render props dot on click it's also going to have a disabled property and there we're going to put the render props dot disabled and it's also going to have a start icon that start icon we're going to import but it's going to be simply icon a self closing component that's simply going to say icon we're going to have one more thing and that one thing is going to be a variant of contained variant is equal to contained i see that we have quite a lot of things some people prefer to have them like this this way it's more easily noticeable what we have and i agree we can leave it like that for now until we actually finish the button so we have the button and finally what can we say in there we can say google sign in now you can see that we're missing the icon property so we have to import that the icon is going to be a simple svg so we're going to create a new file right there called icon.js and now in here we can paste that icon so this is going to be an svg react component and we can simply import it inside of our auth you can again copy and paste this icon it's going to be linked in the description now inside of our auth we simply have to import that icon we can do that easily by saying import icon from dot slash icon as you can see now we have everything that we need in our button so what i prefer to do is to have it in one row because this way it doesn't clutter our view we know that it's a button it has a bunch of props and it says google sign in okay great now we can continue with adding different props to our google login and these props are going to be on success and also on failure so we have two handlers here the handler for success action and for the failure action on success we're gonna call google success function and on failure we're gonna call google failure function we're gonna create both of these functions finally the last thing that we need is going to be cookie policy and that is going to be equal to single underscore host underscore origin okay now we can create those two functions just above inside of here i'm going to create the arrow function for both of these so i'm going to select them both and say const google success and google failure is equal to an arrow function and it's going to be a block of code so what do we do on google success and on google failure well on google failure i simply want to console log an error so in here i'm going to say console.log google and that's going to be a string google sign in was unsuccessful okay and we can say something like try again later okay so this is going to be our google failure and then what do we want to do on success well in here we get access to a full response so i'm going to say rest here and for now i simply want to console.log that res of course this is not going to work out of the box because we still haven't supplied the google login with our client id so we have to find that to get your own client id you have to head to console.developers.google.com i'm going to put this link down in the description instead of here on the left side you'll have a sidebar that says credentials and then odd consent screen first we're going to go to all auth consent screen i already have mine created you'll have to create a new all odd consent screen you can name it something like memories app or something similar and then in here we'll have to do a bit of a setup you can create our app name you can put your user support email and then finally you can add your developer contact information and click save and continue with that you created your odd consent screen in this case under scopes i currently have nothing nothing under test users and this is the summary that's it and finally we can go back to the dashboard now that you have the oauth consent screen you can head under credentials inside of the credentials you can click create new credentials and then you can choose odd client id inside of here you can choose the application type and in our case that's going to be a web application i'm going to call it memories app inside of here you can put the localhost 3000 as the uri and we can also do that for the authorized redirect uris so inside of here we can do something like http localhost and let's do three thousand i think that we can also add the forward slash off to this one with that said we can create it and i think that should be enough localhost 3000 and localhost 3000 forward slash auth for that and there you go you get your oauth client id and the client secret don't forget this site yet we'll have to come back to here once we actually deploy our application because in here you'll have to add a different url because now it works only on our local host okay great so we can copy our client id we can come back to our application and now inside of here we can simply paste that id right in here with that said i'm interested to see what this response is going to be and how does her button look like with so i can close this tab for now and go back to memories project as you can see we have our google sign in button right here looks like it's connected all the way to our front button so what i'm going to do right now is just switch them so i'm going to switch our google login and our normal login button right there so now we have our manual login button on top of our google login and there we go that looks so much better so now the question is if i open the console what is our response going to look like once i click google sign in okay so right now we get redirect uri mismatch that means that we have to go back to our apis and services meaning console.developers.google.com and we have to see if we have set up everything correctly okay inside of here we do see that we have our memories app all odd client so maybe we have to add the localhost 3000 forward slash auth to here as well but you can see that it cannot contain a path or end with that so that's not going to be the solution what about if we add the http right there and not https let's try with that that works so maybe definitely that's the solution let's save it and let's try one more time in our memories app okay if we click the google sign in now as you can see we get this nice window from google but before we go ahead and click anywhere else i just noticed that we have one more thing that we have to do our google success function is going to be asynchronous that means that we have to add an async keyword in front of this function now let's save it go back and now finally let's click that google sign in this is crazy because we didn't code any of this google automatically gave us this window so now i'll try to log in with javascript mastery and take a look at that we got google sign-in was unsuccessful not as i supposed to be but that's normal errors happen so along with this console log google sign in was unsuccessful i'll also try to console log the error so inside of here we can console.log error okay we got an error right there and i'll try to copy the details and paste them right in here so that we can both see what our google says i'm going to extend this into multiple rows usually you should not share your client's id with everyone but i'm gonna delete this after recording the video so it's okay okay so the error says not a valid origin for the client http localhost 3000 has not been whitelisted for client id please go to they give us the url and whitelist origin for your project client id after a bit of googling i found out that the issue was not that we had to add something to our google developers console or something to our code we simply had to clean the cookies so let me show you the solution that they found the solution was in stack overflow and what you simply had to do is clear the browser's cache so in chrome settings advanced clear browsing data cached images and files and that's it that's gonna do the trick so after you do that and come back to the site if you click google sign in take a look right now you can see all the details right here which means our login was successful also while we're here let's get rid of this boring warning it simply says invalid prop input props of type boolean supply to forward draft text field that means that if we go back into our input component right here this is getting a boolean and that means that in this case we cannot use the end end we rather have to use the null because this cannot be a boolean it has to be a null or a specific component so if we save that the error is gone and as we discussed our sign in works beautifully now we have to use some of these details we got right in our response and we can use them right inside of here odd google success now we have access to this entire object so what do we need well we can say const result is equal to res and now we can use the optional chaining operator the question mark dot the question mark dot is a special operator that's not going to throw an error if we don't have access to the rest object because maybe sometimes we're not going to have this rest object so we want to make sure that we don't get an error if we don't have it that way you can say profile i'll be j so now we are not going to get an error if this doesn't exist before if you use just the dot if the rest object didn't exist then you would get an error saying cannot get property profile obj off undefined because res profile obj would be undefined if you do this it's not going to throw you an error it's simply going to say undefined that's going to be the value of the result great so now we know how the optional chaining operator works and now that i think about it it's kind of crazy that they knew the exact error message that we would get if we didn't use this yeah so with that said let's continue we also want to get the token and we can get the token from res question mark dot token id so now we have the token and we have the result that's basically everything that we need since we're working with an async function we can use the try and catch block so now if our login is successful we want to dispatch something otherwise we're simply going to console log the error so how do we dispatch something well of course we have to import use dispatch from redux so inside of here i'm going to say import use dispatch and that's going to be coming from react dash redux of course since it's a hook you need to say cons this patch is equal to use dispatch and finally we can use that dispatch dispatch an action so we can say this patch call it as a function and now inside of there we can send some data in the type of our action is going to be simply auth and then the data we'll be sending in is going to be the payload and all that we want to send is a new object that contains the result and the token that is going to be it now that we are dispatching this action and we're sending the payload in the only thing we have to do is add reducer that's going to handle it properly so let's go to our reducers folder and then in there we need to create the reducers for the auth so inside of here i'm going to say new file off dot js inside of here as always we need to create a basic reducer so we're going to do the same thing that we did in the post first we need to import some of the constants in this case we're not going to have these what we want to have is going to be the auth and the logout of course these are constants in the action types constants so we can go to this folder action types and now inside of here let's create those export const and that is going to be auth is equal to a string of auth and this one is also going to be log out just to reiterate we are doing this to save ourselves the trouble of accidentally misspelling a variable because that way we wouldn't have the error this way since everything is a variable if we misspell something we are going to get an error okay let's create our reducer const odd reducer reducers are functions more specifically functions that are accepting the state and an action based on that they have a switch case in the switch case we're looking for the action.type in this case it can be something like odd and it can also be log out which we're going to implement later on so if our action type is equal to odd what do we want to do well remember we're getting all the details inside of the action dot payload or more specifically we call the data so let's first try to console.log that to see what are we getting so inside of here i'll try to get action dot data i'm also going to use the question mark because not always is that data going to be there and that's it let's try to console.log it and see if we're getting it of course we have to export default auth reducer and we also have to use it in the index.js of our reducers so in our index.js we have to import not only the post reducer but also the auth reducer and then we have to use it here in combine reducers and combine the odd as well not to forget we always have to return something so if we don't have any case in here i'm gonna return just the old state but in this case we also need to return something so for now until we're just cons logging things i'm gonna just return the state and right now our state is undefined so we have to give it a default value so i'm going to say equal to and now i'm going to say odd data is equal to null so if we don't have anything our odd theta of the state is simply going to be set to nothing if we save that let's take a look what do we get okay one more time to the process click google sign in okay and take a look this is our whole thing we have a result in here we have javascript mastery we have our google id and we have our token that's all that we need so what do we do with that well we want to save it in the local storage because that way once we refresh the page the browser is still going to know that we are logged in so to do that we can say local storage dot set item is equal to profile then we want to say json.stringify and then there we want to say dot action question mark data this is it so we are setting all of this that we have all of the data for the login we're setting that to the local storage finally at the end we want to return something we're going to return da da dot state and then we want to specify the odd data to be equal to action dot data and this action data is also going to use optional chaining so this is it for the auth now that we have this return right there and we are setting our profile with the data field for the user we can try to use it somewhere the best place to use it would be a navbar because in here we already have our user which is currently set to null so now let's try to add a real user in here to do that we can create a new state field and we can do something like user cons user and set user and finally in there we can use the use state use state of course has to be imported so inside of here i'm going to import the use state as well as the use effect because we'll need to use that later on now this year's effect is going to be a bit different we're immediately going to try to fetch something and that something is going to be the actual user so how do we retrieve something from the local storage we say json.parse localstorage.getitem and then you specify the name of that item in this case it is going to be the profile so this is how we can get the user right here now that we have the user let's try to simply cons a login console.log user i'm going to go back to the browser and refresh the page so currently the user is null because remember last time we didn't save it in the local storage so if i open the application tab and right here refresh you can see we don't have anything in the local storage but now let me try to log in one more time with my google account and there we go we have our complete information now if i go to memories it are we going to get the console log with that profile it is still null if we refresh though it is there and as you can see this automatically filled with javascript mastery and my icon so that is amazing one bad thing is that we had to refresh and manually head back to the local host 3000 and not the login form so let's re-navigate automatically so we don't have to do it manually we can do that using a use effect inside of here i'm going to use a use it's going to accept a callback function and of course it needs to have a dependency array in this use effect we're going to check for the token so we're going to say if token exists user and then question mark dot the optional chaining token so we're checking if the token exists and if it does we're sending it to the token variable then finally later on we're going to check for the json web token here if we do the manual sign up but now we're using google so we don't have to do that but what we can do is we can say set user and set user is equal to again the same thing that thing is going to be our user json.parse localstorage.getitem and finally we have to do one more change in the auth more specifically once we dispatch this we actually have to redirect back to the home so for that we can use history dot push like this and where do we push to we push to forward slash history belongs to react router dom so we have to import that import use history from react router dom and then right in here we need to say const history is equal to use history and call it of course okay so now this should redirect us immediately to the home page once we log in let's try to log out oh our logout doesn't work right now but if we head manually to forward slash auth there we go and we can click google sign in once that is done as you saw we were automatically redirected the thing that would make sense to do right now is to simply do the logout so that's going to be our next step to implement the logout we of course have to find where this button is and as you can see it is in the nav bar so if we go right here let's find that button log out and we're going to add an on click listener what are we going to do on the on click we're simply going to log out that logout is going to be one function inside of this nav bar more specifically const logout is equal to an arrow function and what are we going to do we're going to dispatch an action so we have to first import use dispatch from react redux and then in here at the top we need to say const dispatch is equal to use dispatch there we go now in the logout what we can simply say is dispatch and we're dispatching an action that has a type of we can do just a string of logout and that's going to be it once we log out we also want to redirect to the main route so i'm going to say history dot push and also we have to import that history so at the top we're going to say import use history from that's going to be react router dom i see that we already have it so i'm going to move the import right here and how do we get it well cons history is equal to use history so once somebody logs out we're going to push them to the root route to the home there we go what do we also have to do is we have to set the user equal to null so if somebody is logged out the user has to be null okay and i think with that right now we don't even need this use effect we're going to need that for the json web token so i'm going to comment that out and let's see if our flow now completely works so we are right there i'm going to refresh the page i logged out there we go we are logged out i'll check the application tab looks like we still have our profile there and as you can see if we refresh it comes back that means that we haven't fully implemented the logout dispatch so we need to go to reducers off and then in here we have to do something if we log out more specifically it is going to be really simple if we have the logout case like this then what we have to do is say localstorage.clear this is going to completely clear the entire local storage and what we want to return well the same thing that we're turning right here except the odd data is going to stay null okay great so now if we go back refresh the page we have our javascript mastery there i'm going to click log out as you can see the console was cleared and if i refresh there we go our user is still logged out now let's try to go to the whole process of signing in go here sign in using google there we go we are logged in and as you can see our profile is populated and when we refresh we get this javascript mastery i don't like that we had to refresh to get the user who's logged in name so we have to go back and looks like that in the nav bar which is right here we still need that use effect so i'm going to add that use effect so when do we want to call this use effect as soon as the url changes from the forward slash auth to the simply forward slash and we can use the property use location from react router dom we need to do the same thing const location is equal to use location and based on this we'll have access to that change when this changes we want to simply call the user when location changes i can put that right here when location changes simply set the user now let's take a look if that's going to work if i go back log out one more time login and there we go now we immediately got this user right there because we automatically set the user profile once we came back from the forward slash auth and it was populated amazing and now if you refresh the page go back go somewhere else you're still going to be logged in for i think about an hour because our token lasts for about an hour or if you want to manually log out you can simply do that right away crazy how simple the google all aud system is right we implemented this in a really short amount of time next step is to implement the manual login and registration system using the json web token for that we're going to use this form that we created let's start working on that i'm going to close all of these files just so we have a clean working environment i'm also going to collapse all the files and folders so this is now going to be a first time in this video that we are going to focus on the back end as well because we have to create the models for the user as well as the controllers and the routes for the login and registration for now let's handle the client side of the authentication system to do that we have to go to our odd form right inside of here and now remember whenever you're working on something take a look at the actual jsx and then ask yourself when is this happening and the answer is our login and registration is happening after the user clicks this button that means that we have to focus to implement actions once this button is clicked going back to here we can see that our button is right here if you take a closer look at this button you can see that once you click it it is of type submit that means that the only thing it does is it calls this on submit function in this case the on submit function is the handle submit so let's see where is that and there we go it's right in here more specifically it is empty so we're not doing anything with it right now now what do we have to do with it to make our login work first thing to do would be to check if we have access to all of the state fields more specifically are the values of these inputs in the state and right now we cannot see that we are mentioning state nowhere right and while we're here i also noticed that this should be a last name and also in here a last name yeah so we are never ever mentioning state so how can we do that well let's create a new state field right inside of here const and we can call it something like form data form data set form data and that is going to be equal to use state of course we have to make this use state at the start be equal to something so just at the top of our component let's create a new field const initial state is going to be equal to and now in here we have to put the initial values for all of the state fields that is going to be for example the first name which is going to be equal to an empty string then we have the last name also equal to an empty string we have the email again everything is going to be an empty string we have the password and we have the confirm password also equal to an empty string and that is going to be it for our initial state now how do we use it well you simply put it in here that is going to be the initial state of the form data okay now let's try to console.log the form data on submit and obviously immediately considering that we are never setting form data we expect that to be empty so let's take a look if we go back in here if i type something and if i type a password i'm going to open up the console right here and click sign in and first of all it immediately refreshed that's because it is the default behavior of the browser to refresh on form submit so we have to add the event in here we get the event e dot prevent default that is something that you always add on the form submit in react because there we don't prefer reloads we always want to have something on the screen so with that said let's see if we get something there i'm going to type the same thing one more time and click sign in and as we expected we got all of the fields there because that is our initial state but they are all an empty string now the question is how can we populate these fields and the easy answer is to look just a bit below our handle submit we have the handle change and each one of our inputs is using that handle change but right now it is empty so what do we have to do to fill it well in here we get the actual event and then what we can do is say set form data we get an object right we spread the form dot form data and then we update only a specific input that we're currently managing and the question is how can we know on which input are we currently well each one of the inputs has its own name first of all you have to make sure that your names are exactly the same as the names in the initial state right here first name last name email password confirm password and so on if that's the case you can use these square brackets right there and say e dot target dot name and that's going to be equal to e dot target dot value this is going to make sure to spread all of the other properties but only change the one specific one you're currently on with the target value that means the current input that we have in there with that said if we save that let's try one more time and see what we have in this form so i'll first try to enter something and there we go we have our email and we have our password if i switch to here we have our first name and if i click sign up there we go we have all of our values listed right in here so that's why we had to use the same handle change function for each one because otherwise because otherwise you would have to change each state field separately which is quite a lot of code this way it is a lot easier this is dynamic and works for infinite number of fields with that said that's great now we have our handle submit but the question is what do we want to do on that submit well they're going to be two different types of submits one is going to be our sign up and the other one is going to be our sign in so we already have a variable to check that so we can say if is sign up in that case we want to do the logic to sign up the user else if we're not on the sign up we want to do the logic to sign in the user so in this case what we want to do is we want to dispatch an action and more specifically that is going to be a sign up action and to that action we want to pass in the entire form data and we also want to pass the history we pass the form data so well we can have it in our database of course but we pass the history object so that we can navigate once something happens okay great and the other one we can copy this and simply put it right there this one is going to be sign in all of these are actions that we have to import first so just above i'm going to import these two actions inside of here i'm going to say import sign in and sign up and that's going to be from dot slash dot slash actions and then auth this file doesn't exist yet but we're going to create it right now okay so if we save that we are ready to start creating the actions file that's going to be inside of the actions and we simply need to do auth.js inside of here we can start creating our odd actions first of all we're going to need some things from here like constants action types and all the things from the api so let's copy these and simply paste them right here in this case we won't need those the ones that we need is simply going to be auth and from the api later on we're going to use some of the calls but right now we don't need anything so let's start with creating the actions while we're creating them we can also export them that's going to mean export const and we named it sign in that is going to be an action creator which is a function that simply returns an action and as we discussed in the last video if actions or more specifically action creators are asynchronous then we have to use redux tank meaning we have a function that returns an async function with a dispatch i know it's a crazy syntax but we just have to follow the rules in this case so we have this and then we have async dispatch function which then has a function block in here we get what we passed into our function so we passed the form data and we passed in the history so we can repeat that here form data and history if we're in an async block of code we can use the try and catch and now in here we can do the logic if you remember what we were doing in the posts actions you can see that in here we're trying to fetch some of the things from the database and that's going to be the same thing that we're going to do right in here in here we're going to try to get the data for the sign in or rather we're going to send the data to the database or to the backend so that it knows to sign in the user right now we don't have the back end endpoints for this to actually work so this is going to be a good time to transfer back to the backend before we do that though let's just create a complete mock of the sign in and the sign up and then we'll move to the back end so for now in here i'm just going to say log in the user and then finally why do we have that history because we want to navigate to the home page so that means that we can do history dot push and then simply push the slash after we log in the user we push to the home page and then in the catch for now we can simply console log the error okay and now i'm gonna copy this and do the same thing for the sign up i'm gonna just rename this to sign up we also get the form data and the history we get the dispatch and in this case we need to sign up the user and then finally we navigate to the home page and console log the error and now we're pretty much done with the front-end side for now of course later on on the back end while we create those endpoints then in here we'll be able to call them but for now there's not really a lot we can do on the front-end side now we need to move to the back end create the user model create the controllers and the routes and then we'll be able to continue so let's do that as before i closed all the windows collapsed the folders and let's start with the back end we can focus on the routes first more specifically in the index.js we need to add the routes for the users so inside of here i'm gonna say app.use we're gonna use the user endpoint and then in that case we're gonna have the routes called user routes those user routes as you can see they're undefined yet but we have to import them as we imported the post routes so i'm going to copy this line and just change this to user routes and that's going to be coming from dot slash routes and users.js now we know that we have to create the routes right inside of here users.js so how are these routes going to look like well first we have to have the basic structure as we already have with this thing we have to import express from express then we have to get some of the controllers from our controllers right now we don't have any then we have to create the instance of a router and finally we have to export the folder router before we export the router we of course have to add those routes and you add them in the following manner router that and this is going to be a post route to forward slash sign in why is this a post route because you have to send some data to the back end more specifically you have to send all of the details from the form to the back end the form sign in and sign up is the best way to explain how does the post request work you need it to be a post request because you have to send all of the information from the login form to the backend and then and then back and does something based on that information in this case it's going to sign in the user so what are we going to do when we go to the sign in well we're going to call our sign in controller and i'm going to copy this one more time we have the sign up as well and this is going to be sign up obviously these are undefined right now so let's import them from here sign in and also sign up of course these are not coming from the posts they will be coming from user.js of controllers so in here we can create user.js of controllers and this is going to be the place where we're going to put all the complex logic of actually signing in and signing up the user in this file we're gonna need a few things first we're gonna need a package called bcrypt bcrypt is used to hash the password of course if you're creating your users users want to have some security if your database is hacked and if you're storing your passwords in a plain text everybody will be able to see it if you hash the passwords that won't be the case that's why we use bcrypt we can say import bcrypt from bcrypt js like this and we also need jwt jwt stands for json web token and that is a safe way for us to store the users or more specifically store the user in a browser for some period of time for example for an hour 2 hour or even a week that way if user leaves the site he will still be able to stay logged in no matter what in this file we have to use the user model which we haven't created yet so now would be a good time to create the user model inside of here i'm going to create a user.js file that is inside of the models now the situation is going to be similar to what we have with the post message we have to import mongoose we have to create a schema and finally we have to create a model which we then export so let's repeat the process import mongoose from mongoose then const user schema is equal to mongoose dot schema make sure to put the capital s right here and there we have an object now inside of that object you put all of the necessary details we have a name and name is going to be required so inside of here we can say name type is going to be of a string and required is going to be set to true then we have an email email is also going to be of a type string and required is going to be set to true we have a password password is also going to be of a type string and the required is going to be set to true and then we have the id id is going to have a type of string and that is going to be it for this user schema finally we can say export default mongoose dot model you need to specify the user model with a capital u and you need to specify a schema on which that model is built upon and in this case that is going to be the user schema now in the controllers we can import that model the user model and then based on that we can create a lot of instances of users our memories learn project users so for that we can say import user from dot slash models slash user dot js and now we can create our controllers we know that we need to have two one is going to be export const sign in and that is going to be an async function on all of the controllers we have the rec and the res which is the request and the response and we have a function block this is going to be the function for the sign in and i'm going to copy this and simply replicate it for the sign up so now the question is how does the logic for the sign in and the sign up look like that could be a complex part right well both yes and no it can be daunting if you're just starting with it or if you're trying to build this yourself for the first time but in this case you're watching this tutorial and i'll try to be as turo as possible and guide you step by step through how to do this usually all sign in sign up projects are similar in any application you need to have a sign-in system so once you know how to do this once you'll be able to mostly duplicate the code and achieve the same purpose in any app that you build first of all for the sign in we're going to get two things from the front end and those things are going to be the email and the password so the question is how are we getting it from the front end whenever you have a post request you get all the data through the request.body we can say const and then the structure the email and the password from rec.body so we're destructuring that all the post data that you send is going to be available for you in direct.body okay now that we have these values what do we do well we are in an async block so i'm going to open a try and catch if we are signing in we first have to find the old user right so i can say const old or we can better say existing user existing user and that is going to be equal to a weight user dot find one and we find the user by email that means that we are searching for the existing user in the database because if you're signing in we cannot simply create a new one we need to find the old one already existing in the database in this case we're going to say if no existing user then we're going to simply return rest.status 404 because it means we cannot find it and then dot json the message is going to be equal to user doesn't exist that is it that's if we don't have the existing user in the database if that is not the case we have to check if the password is correct so if the new password that user typed in is the same one to the password used when he or she initially created the account we can say cons is password correct and that is going to be equal to a weight bcrypt dot compare and what we want to compare is the password to existing user dot password we cannot simply do a normal string check because before or rather later when we implement the bcrypt we're going to hash the password so we still have to use bcrypt to compare the hashed passwords and see if they're the same then we can do one more check and say if no is password correct so if the password is not correct return res that status that's going to be 400 dot json and in there we're going to have a message and what we can say is simply invalid credentials okay that's that's good and moving on if the user already exists in the database and if the password is correct then we can finally get his json web token that we need to send to the front end so to do that i'm going to say const token is equal to jsonwebtoken.sign and in there we have to provide all the information that we want to store in the token in this case we could store the email email is going to be equal to existing user dot email and we also want to keep the id which is going to be equal to existing user dot id or it's going to be that underscore id don't forget that underscore with the id the second argument to the json web token sign is the secret instead of here you have to have the secret string that only you know usually you would put it in a separate env file where you store all of your variables where nobody else can see in this case we can simply say test right there and that is going to be enough as this is a youtube video i'm trying to keep it as concise as possible if you'd like me to make a separate video of this series where i go through the entire project and just apply all of the best possible programming habits to it like move all of the things that should be saved to somewhere else and refactor the code and so on feel free to let me know in the comments for now we're gonna simply leave this as test finally the last thing is the options object so inside of here one of the options we'll use is expires in and we're gonna say expires in one hour just one h and that is going to be it for our token finally now that we have the token the last thing that we have to do is simply return it so we can say rest.status status is going to be equal to 200 and json what are we sending we're sending the result which is going to be equal to the existing user or rather the user that's trying to log in and we send over the token that we just created here on the back end if the token creation didn't win successfully we can say rest.status 500 that means an undefined server error and then we can say json and what are we returning well just a message that says something went wrong we don't really have the info on what went wrong and this is it this is our sign in controller of course more important part at least right now is to create a sign up that way we'll be able to add the users to the database so let's add the sign up right now it's going to be quite similar but it's going to have a few distinctive differences again we want to get something from the reg.body rec.body we are destructuring the things that we send over and remember what we have on the front-end side when we are signing up we have first of all the email password and then we have the first name and the last name as well we also have the confirm password field don't forget about that okay so now that we're getting all the data let's start with the logic we again have the try and catch block and in this case we are also going to try to find the existing user so we can say const existing user and this is going to be the same as we had right here so we try to find a user with that email why do we do that if you're signing up think about it we cannot create an account if there already is an existing user so in this case i'm going to copy the same line that we have right there but in this case i'm not going to say if not existing user i'm going to say if existing user that's the problem right there and then what do we want to return res the status that's going to be 400 and we're gonna say user already exists moving forward if we don't have the existing user that means that we're good to go to create an account but we first have to check if the password is the same to the confirmed password so we can say password is equal to confirm password or rather we can say if the password is not equal to to the confirmed password in that case we're going to return the same error right here so i'm going to paste that return and in this case we're going to say passwords don't match that's that means that the user has to re-enter them one more time okay great moving forward if we don't have the existing user and if the passwords match that means that we're good to go to create the user before we create him though we have to hash the password because we don't want to store it in a plain text to do that we can say const hashed password and that's going to be equal to a weight bcrypt dot hash and then in here we simply pass in the password the second thing that you pass is called salt and that is the level of difficulty that you want to use to hash your password people usually use 12. okay so now that we have the hashed password we have to create our user i'm going to say const result is going to be equal to await user dot create and how do we create a user we have to pass in all the data we pass in the email we pass in the password but take care it's going to be hashed password in this case then we pass the name the name in this case is going to be a template string where we first take the first name and then add a comma and then add a space and then enter the last name so we're gonna combine the first name and the last name together just like this okay now that we created the user we also have to create the token so i'm going to copy this line from above cons token is equal to json wt jsonwebtoken.sign email is going to be equal to that email and id is going to be equal to result dot underscore id the secret is going to stay the same and expires in is also going to stay the same finally after this is all successful we have to return our user so i'm going to copy the return from the line above and what we can say is rest status 200 means everything went good and we send the result in this case the user itself is the result and we also send in the token if something went wrong of course in here we can simply send res that status 500 something went wrong and this is it now we have the controllers for the sign in and the sign up this alone should be able to allow us to log in and register i'm really trying to be turo explaining this because i know it's a hard concept i'm really glad we went through this hard part it's definitely not easy so make sure to re-watch it if you don't understand some of the parts if you like my current way of teaching definitely make sure to leave a like and comment it really helps with the youtube algorithm with that said let's move to the second step and that is once the user is actually logged in he can do all kinds of actions he can delete a post that he created he can like it he can like all the other posts and their backend needs to be able to basically say okay you are allowed to do that you are real user you're currently logged in and you can do that for that we use something known as middleware so our next step is going to be creating authentication middleware to create any kind of middleware we can create a middleware folder so right inside of the server we can create a middle where folder you can see if you use some kind of icon theme like material ui icons it's automatically going to get a different look inside of there i'm simply going to say off dot js because the middleware inside of here is going to be for auth right now you might not understand what a middleware means it's a specific name but as soon as we create it i'm going to show you where that piece of the puzzle is going to fit in as i show you that it's going to make complete sense so for now let's start with the middleware we're going to import jwt from json web token then we're going to create our odd function so we can say const auth and it's going to be equal to an async function where we have a rec res and the next even by looking at this you can immediately see that our middleware is really similar to what we have on our controllers they all have the wreck and the res but our odd middleware has something known as next that means do something and then move to the next thing again you're gonna see it in just a few moments in action but now inside of there we're gonna add a try and catch block for the catch we're gonna simply console.log the error for now and now in the try block we have to see if the user is really who he is claiming to be and we can do that using jsonwebtoken so after the user is signed up or signed in he gets this specific token now when he wants to do something like like a post or delete a post we have to check if his token is valid and that's what we're doing right here so to get the token from the front end we can say cons token is equal to rec dot headers dot authorization dot split so we split it and we only want the token itself and the token is on the first position in the array after we split it then we're gonna have two kinds of tokens we're gonna have the one from the google auth and we're gonna have our own so inside of here we can decide if it is our own or to google auth that's going to be a variable we're going to say is custom off and if the token dot length is lower than 500 then it means that it is our own if token length is greater than 500 that is going to be google auth then we can create a variable called decoded data so that is the data that we want to get from the token itself and now finally if we have the token and if the token is our own so if it is a custom auth in that case we want to set the decoded data to be equal to json web token dot verify this is going to give us the data from each specific token it's going to give us the username of the person and its id inside of here we have to pass the token and we need to have that secret we were talking about in this case we know that the secret is test it has to be the same secret you used when you were creating that specific token you can see right here we use test and in here we use test and now that we have the decoded data we know which user is logged in and which user is for example liking the post or deleting the post so we're going to store his id in direct dot user id so reg.user id is going to be equal to decoded data question mark dot for the optional chaining id okay this is how we get the user's id if we are working with our own token and if you're working with the google's or token we're gonna do the same thing decoded data is going to be equal to json web token dot decode in this case it's going to be the code and simply pass in the token in this case we don't need the secret once we have that the situation is going to be similar rec dot user id is equal to decoded data question mark dot and in this case we're going to say something known as sub sub is simply google's name for a specific id that differentiates every single google user basically it's an id that we can differentiate the users with finally we can call the next so that we can pass the action onto the second thing for example if the user wanted to like a post so let's say a user went and he wants to like a post wants to like a post he has to do this click the like button and then this is what happens first we don't immediately like it because we are not sure if he has permissions to like it first we go through the odd middleware okay auth middleware confirms or denies that request so if all of this is correct we're going to call the next and we're going to say okay you're okay to like that post so if auth middleware says okay you're good to go only then are we going to call the like controller and this is what middleware is for for any kind of action that happens before something this next thing is crucial we are saying do this and then do something next do something after this is done and that is a middleware okay with that said we can finally export default auth now the question is where do we use that auth middleware and the answer is in the routes for example we said when somebody likes something in that case we want to use that middleware so first of all let's import it import auth from dot slash middleware auth and we're on the back end so we have to do the odd.js okay this is going to be our middleware now we want to add it before specific actions for example all of the users no matter if they're logged in or not they can see all the posts but to create a post you need to have your own id you need to be logged in then in this case i noticed that this is an extra action that we don't need so we can delete this one because we don't have a specific memory page we can implement that in one of the future videos then we have the edit post or update post in there we definitely need to have the auth happening before because we need to see if the user has the permission to update a post same thing happens for deletion do we have the right to delete that post and finally the same thing happens for liking why although everybody has the permission to like something he cannot like twice or three times that's why we need to call the odd before to have the specific user's id and he can only like once for that specific id great now you know how to create auth and also where to add it now the majority of our back-end work is done but we still have to implement the logic for for example liking only one specific post right now you can like as many times as you want we also need to implement the logic for deleting only the post that you created or same for updating the posts only you created you cannot simply update or delete any post that's there and that's going to be it this one the like post is going to be managed on the backend and if i'm not mistaken the delete post and update post are going to be managed on the front end because what we have to do to disable user from deleting something well if he is not the creator of the post simply remove the delete button it's not going to even be there he won't be able to click it there we go so while we're in the back end we're going to focus on completing it so now our next step is to implement the like post only a single one and then we're going to move to the front end to finalize the things with the auth and with the update and delete post starting with the light controller that's the one that we created in the last video inside of the post js of controllers if you scroll a bit down you should see a like post controller now we have to modify it so that the users can only like the post once so let's do that first of all we have to see if a user is even authenticated we can do that because now we have that special value and that is rec dot user id this is really really important to mention if you call a middleware like this before a specific action like in this case then you can populate the request and then you'll have access to that request right into the next action that you have so if we go into our auth and then in here if we populate the request.userid then we go to the next controller in the row which is going to be the like post and now the request is going to have that user id property with this we can check something we can say if no rec dot user id that means that the user is not authenticated and we can simply say return res.json and then message is going to be equal to on authenticated in here we have the same old check to see if we do have the post that the user wants to like then we get the actual post and now we have to see if the user's id is already in the like section or is it not so we can say const index is equal to post dot likes dot find index inside of here we have a callback function where we loop through all the ids so each like is going to be the id from a specific person that's how we're going to know who liked the specific post and what we have to do is we have to say if id is equal to we have to convert his user id to a string and then we can say if the id is equal to string of rec.user id if that is the case that means that his id is already in there that means that that person already liked the post and this is going to be a dislike and not the like so how do we do that we can say if index is triple equal to -1 only if his id is not in here only then is this going to be equal to -1 so this is if he wants to like the post else we're gonna get the index of his specific like in that case we want to delete his like or rather dislike a post great so what is going to be the logic for adding the like that is going to be really simple post dot likes dot push rec dot user id we're basically just pushing his id and if we want to remove his like we need to remove his id from the likes array that's going to be like this pose.likes is equal to post dot likes dot filter our filter accepts a callback function and it's going to loop through all the ids you can see likes are going to be ids and then in here we have to filter out the like from the current person we can do that by saying id is not equal to string of rec dot user id and this is simply going to return us the array of all the likes besides the current person's like now that we have the current number of likes we are going to create the updated post and that is going to be the same as we have it here post message defined by id and update but in this case we are not going to update only the likes or the like count we don't have that anymore we are simply going to create a new post so the pose that we had we're going to update it because now we have the same old post that now includes the like itself one more thing that we have to do is add the actual likes to each post that is going to be in the post message model right here so far what we had was the like count we no longer have the like count we're gonna have likes the array of likes inside of there the type is actually going to be an array of strings this is how we write that so the array of ids and then the default value is going to be an empty array great now this is done make sure to save all the files and now we will be able to go to the frontend part and see if we can make the calls to the sign in and the sign up routes and controllers this is the thing with back end if you work with the back end most likely you have to write a lot of things and not visually see something that's just how it is with the back end but now we're going to move back to the front end since we're building a full stack app and we will be able to see the logic that we implemented on the back end i closed all the windows just so it's easier for us to go back to the front end and let's focus on important things inside of our actions more specifically auth actions we said that we need to log in the user but at the time we didn't have the actual endpoints on the back end that we needed to contact now we do have them so that is our next step to log in or to sign up the user for that we're first going to create api endpoints like we did for all of our actions with the posts now we need to create these only for the authentication before we start with that we're first going to do some updates to our current setup i'm going to create an axios instance const api and that is going to be equal to axios dot create inside of here we can create a base url so you can put options like this an mta object and then inside of there you can specify the base url now we're going to set the base url to be a string of http forward slash localhost and then 5000 just like so we don't want to have that for slash posts because now we're going to have the api also to make some different calls for example to the users and not only to the posts now we can delete this and now instead of two axios we'll be making all of our requests to the uppercase api this is going to do the same thing absolutely the same thing but now you don't have to specify the starting part of this url so how do you change that well now it's not going to be api.get forward slash url it is simply going to be forward slash posts we always have to add that in this case we also want to reach out to something like forward slash posts that's the same in this case it is going to be forward slash posts and then forward slash id and then forward slash like post in this case posts only forward slash post and in this case also posts we already have the id we did that so that later on we can use some more advanced features of axios some of the features that are not often mentioned in easy tutorials and are definitely a good thing to know before that though let's simply create the routes for the sign in and the sign up export const sign in that is going to be an error function and that arrow function is going to accept the form data so what do we call once we make that request api.post and that's going to be a post request to forward slash users forward slash sign in finally as the post payload we want to send the form data i'm going to replicate this request and we're just gonna rename it to sign up right here and we also have to rename it right here sign up everything else should be the same with that said we can go back to our actions right here and now we have those api calls the sign in and the sign up so what we can do is we can say const destructure the data from a request and make that equal to a weight api dot sign in of course we have to pass the form data and i know this redux flow can be confusing like we have this form data here we have it in the api then we're passing it from here where is that coming from where is that going to how do we get the reducers i know that can be confusing so one more time let me give you the whole explanation of the redux workflow first we get to the actual form the form is a component right here in the auth once we fill in all the inputs we want to dispatch something this patch immediately has something to do with redux we are dispatching an action this action is called sign up for example let's do sign in in this case so we're dispatching a sign in action and we're giving it two different things the form data and the history once we dispatch that we come to our actions and that is this thing we're dispatching this whole action now this action makes another call to our api just so we know where we're going and it's basically this it makes a post request says hey database get me some data and return it to me and we write in our action that's what we do we get some data and we get it right there finally from our action creator we can finally dispatch some things and then we're coming into our reducers so in this case once we have the data we want to dispatch an action with a type of auth and we want to pass over the data to our reducer now we're going to repeat the same process for the sign up it is identical so in here we get the same thing but we change this from sign in to sign up and with that our odd actions are done now we have to see if our odd reducers are also done inside of here we're getting the profile and then we are setting it to the local storage so this part also seems to be done for now to check if it works i'm going to save all the files and go back to the browser okay once we are here for now we cannot see the posts but that's okay let's try to sign up inside of here we have to sign in but let's first create an account let's do something like john wick and that is going to be john wick gmail.com the password is going to be one two three one two three first of all obviously something is wrong right there because our input is not hidden it's not a password and then our repeat password looks okay so let's go ahead and check what's wrong with that why don't we have our password that is going to be in the auth more specifically in the password field so that should be right here so if the show password is true then set that to text otherwise show that to password okay that seems to be great but maybe our show password is wrong so let's check the show password show password by default should be set to false and it is so where does the error seem to be let's check that out well one thing that i can notice is that in here in the switch mode we're calling handle show password and setting that to false we simply should have um called the set show password and set that to false so inside of here i'm gonna change this to set show password let's save that and see if it makes a difference okay now it's good but i still don't see that icon on the right side that lets me toggle this thing so let's see what is wrong with that so if i go back right there and that's going to be inside of our input component so i'm going to head there let's see so if name is equal to password oh there we go password what is a password javascript doesn't know that so obviously we have to make this password now if we save that let's see if that is going to make a difference there we go now we have this nice icon we can we can again go as john wick john wick one two three one two three let's see if we made a mistake we haven't that's really good and finally repeat password one two three one two three now i'm gonna collapse this i'm gonna clear the console and go to the application tab in here let's see if our local storage is going to be populated with our newly created profile i'm going to click sign up right now and looks like something did not work and don't worry i just wanted to show you that this is the thing that usually happens remember for the past half an hour or so we worked on the back end solely we didn't check for mistakes we didn't see if anything goes wrong we just went ahead and tested it usually when you change something for a bigger amount of time it's not going to work the first time you test it that's just what i wanted to show you so right now we have 404 and looks like it's just psi up so it's just one more typo and this is going to be happening on the front-end side i think so if i go back to the code to our api there we go sign up so we're just missing that n right here with that changed let's try to make another request john wick again john wick one two three one two three and let's test it out again i'm gonna open the application tab to see if our local storage is going to get populated sign up and again we have an error sign up not found localhost 5000 forward slash users forward slash sign up okay so now i see that we're making a request to the correct route localhost 5000 forward slash users forward slash sign up let's see what seems to be the problem i think that on the back end in our routes more specifically in the index.js of the server we said user not users so again it's just a small typo where you have to be really concise with the routes on the back end and the routes on the front end so now that i change this to user it should work right now again john wick one two three one two three and let's test it out okay there we go looks like we are logged in we have our j right there john wick and let's open the application tab and would you look at that we have our email we have our name our password which is now hashed take a look at this this is not one two three one three this is a complete hash of the password and finally we have the backend generated token which stores all the information about the user so now if i reverse the page the user shouldn't be logged out and there we go he is not he is still here finally can we log out the answer is yes we can and to test our sign in let's go with john wick one more time one two three one two three and test it out okay with the sign in we again got a warning or an error saying user okay it looks like i'm missing the end right there you guys are sure seeing this and are like oh you missed the end there so okay now we have it now we should be able to sign in one more time and let's do it there we have it we successfully created the account stored it in the database registered and logged in and the login is also persistent you can refresh all the way you want the user is still going to be signed in for an hour or until he presses logout now our next step is to check if the user can do all of the user actions like creating a post or deleting a post or maybe liking some posts so that's going to be our next step before we check for all of these actions though there's one more thing that we have to do and that is going to be in the api remember how i told you that we created this axios instance so that we can add one more thing to it and that one thing is going to help our odd middleware our middleware cannot work without that one thing and that thing is adding something specific to each one of our requests how do we do that we can say api.interceptors and dot request this is going to be a function that's going to happen on each one of our requests so in here we can say dot use and then you provide a callback function that callback function gets a request as the first parameter so again this is going to happen before all of these requests so why do we need this because we have to send our token back to our backend so that the backend middleware can verify that we are actually logged in for that we can say if localstorage.getitem and we want to get the item of profile that's where we store the token so if that exists then we want to add something to our request and that something is going to be rec dot headers dot authorization just like this remember if we go to the back end and take a look at our middleware right here you can see that we're taking something from rec dot heather's dot authorization and now that they look at it this must be uppercased great so now let's take a look rec.headers.authorization in here we need to put our token and the token is going to be a string and it needs to start with the word bearer so this is going to be a bare token the first thing is the bearer just a string and then the second thing divided by a space is the actual token we can get that by saying json json.parse inside of there we get the local storage dot get item we get the profile and then finally if i can close this correctly on that profile we need to say dot token like this so we want to get the token from that specific profile it looks like i'm missing something nope that seems to be it so we're adding the bearer prepending that string to our token and now we're adding that to each and every request finally with interceptors we have to return the actual request so that we can make all these future requests with that our backend will be able to get a specific header and then based on that header we can do what we've done here decode the data and based on that our back end is going to know that our user is indeed logged in so for the user creation now that we have this rack user id on the back end we can head to controllers and posts we've dealt with the like post but we also have to make a change to our create post right here so you can find that create post controller in the post.js controllers and that in here we can make some changes inside of here we don't have to take all of these values because they are just one thing they are the entire post so we want to have the entire post and then we set the new post message to be equal to new post message instead of here we're going to have the entire post so what we can do is first of all spread the values of a specific post and then this is the key part we want to set the creator of the post so creator to be equal to rec dot user id so now our back end automatically specifies the creator of a specific post and then we also want to add a created add property so created add and created that we can set that to be equal to new date call that as a function and then put dot to iso string this is going to make sure that our date definitely shows the value when it was created so these were some of the changes that we had to make to this create post but now that we change this now our creator is no longer going to be the name that we ourself specify it is going to be an id that means that we have to go to our post message model right there and now along with the creator we need to add one more thing and that is going to be a name so we still want to have the name but it is going to be the name of the person who is logged in not something that we can type ourselves before we had to type in our name because we didn't have the login but now we do and that is a great thing i understand that some of these changes are really hard to get a good grasp on if your first time building this thing like what is even json web token how does that relate to middleware and why are we adding headers and a token each time that we send the request from the front end these things can definitely be dawn thing so if you're having some troubles understanding definitely make sure to rewind some of the parts of the video and re-watch them but still one more time i'm going to make sure to go through the whole workflow to explain what's happening this time i'll show all of that in the browser's console so one more time i'll go back right here and we're going to open our network tab i'm going to be looking at the requests that we've made from our front end to the backend before we do that i forgot to remove this creator right here we don't need that anymore so let's change that in our code that is going to be in the form right here so inside of the form we have to remove that creator variable we can completely remove it since we don't need that anymore and are there some other changes yeah we have to remove it from here set both data and is there something else that we want to change yep we have the creator right here as well so we want to delete that okay now we remove that name but how is our backend going to know what name do we use well what you can do is right in here when you're sending that specific user you can add it so if we dispatch a creation right here we can specify the pose data so we can create a new object we can spread the post data so this is not going to change anything that we had so far but now we can add a name property and name is going to be equal to the users that's currently logged in and that user is going to be stored in the local storage so how do we get the user you can say const user is equal to json.parse and then local storage dot get item and then in there you put a string of profile this is going to make sure to grab the user for you now in here we can say user question mark dot that's checking if we currently have the user and then result question mark dot and finally in here is the name of the user all of that is going to be equal to a name if somebody is changing this we also want to keep his username so in this case we're also going to do the same thing create an object spread the post data and finally set the name to be equal to user.result.name one more thing that we can do in here is check if there is no currently logged in users in that case we want to show a card that says no you cannot create a post right now so let's do that if no user question mark dot result question mark dot name in that case we want to return something and that something is going to be a paper like we're wrapping something in paper like our form is wrapped that paper is going to have a class name of classes.paper and then inside of here we're going to simply add one typography that typography is going to be of a variant h6 and it is going to have a line equal to center in there i'm going to type please sign in to create your own memories and like others memories now we can save that and i think that's going to be it with our form let's go back and test it out now we have the title message everything else is the same okay you can head to the network tab and you can clear it now we're going to be looking at the requests that we are making from the front end to the back end again title is going to be something like new year message is going to be happy new year and by the way guys i really wish you a happy new year a wonderful one a productive one have fun enjoy it and i wish it's definitely going to be better than the previous one okay now let's add a tags you know how people do the tax new year happy new year and also let's do 2021 finally i'm going to select an image let's do fireworks and let's submit it there we go you can see that we have 204 requests right here 204 is not good you can see that our post wasn't created but let's open it and see what's in there so 204 means that it didn't went right but let's see what happened in here we can see that we don't have headers at least i don't see them request headers we don't have the headers for the specific token yep they're definitely missing so let me open the application tab and let's see here in the result do we have our token we do it is right in here but for some reason this token wasn't added to our request okay so in this first one we do have all the information from the request payload we have the tags title selected file and the message but in the second request we don't have anything we have to figure out why the post wasn't made on the backend and if we open our code more specifically our terminal we should get some kind of an error from the back end and we do it is right in here cannot read properties split of undefined add auth that is happening on the backend more specifically in the middleware right here it's saying that it cannot read property split off undefined that means that direct.headers wasn't sent so one more time in here i'm going to console.log this time just the rec.headers to see if you're getting absolutely any headers from the front end i'm going to go back and just type some gibberish right here test this test and click submit let's see if this times the headers are being sent looks like they're not if i go back we get the same error again but we do see some headers right there the question is is do we have the authorization and looks like there it is authorization bearer token is right in here so that is good we have them oh but here's the thing first time that i wrote authorization it was correct with lowercase letter no matter how you write it at the front end at the back end it is always going to receive as the lowercase key letter okay so now that this is done there is one more thing that we have to do and that is exchange the creator for name in our post that is going to be right here inside of posts and then post before creator was the name of our person but now it's not going to be the creator it is going to be simply name we change that the creator is now the id of the person who is creating it with that said we can collapse our terminal and potentially go back and try one more time let's go with new year one more time happy new year and in here i'm just gonna do holidays now we're gonna add the fireworks image and let's see our request there we go johnwick's name was immediately populated the timestamp is correct a few seconds ago hashtags are here title is here and everything is here if we take a look in here we get 201 created and we get all of the information for our specific post this is great that means the user can successfully create posts right now you can see that our user also has the edit button and the delete button we still haven't changed those for non-logged in user that's going to be the next step and we also have the like button and now if we log out take a look please sign in to create your own memories and like other people's memories so right now we cannot create new ones if we're not signed in of course the edit delete and like shouldn't be here as well because if you're not logged in you shouldn't be able to do those actions okay so now let's log back in as john wick and let's see if we can like delete and edit these posts we can start with like and looks like our like action is dispatched as you can see that right here on the network tab we have 200 and the like was indeed added under likes and if we remove it let's take a look yeah it was removed that means that the backend for likes works completely but on the front end we are not seeing the changed as you can see we only have the like we don't see the number of likes that we have so that is going to be our next step of course we are seeing likes under the post and post is this component post.js inside of here somewhere we need to have the button to like something and it is indeed here just like and then we have the like count but considering the like count doesn't exist anymore it's not showing it so how do we fix that well this is going to be a bit tougher because you know how it goes with likes like if you have one like and how it goes with grammar at all you have one like but then there are two likes and then three likes and then if you like something but other people don't like something you have to have a different message so to show all of these uh likes and like and different buttons depending on if you liked something or didn't like something i'm going to create a new let's call it a sub component of the post component it is going to be called likes the logic for creating the likes sub component is going to be incredibly simple but you have to write a lot of code to get it right because you have to check for a lot of things so what i'm going to do is i'm simply going to give you the logic for that right here i'm going to paste it because it would take us quite some time to actually go through everything and see what we have so just to go over it we are first checking if a current person likes something or if it didn't like something we can check that in two ways we're checking if the likes array contains the id of the current person and that can be either the google id if the person did the auth or it can be a custom id from the database if that is the case we want to say you and a certain number of people like something or the post has one like or multiple likes you can see the s there and then if the person didn't like it we can just say the number of like or likes and so on and then if nothing happen if you're the first to like it it's just like so a lot of things happening here but again just wanted to give you a bit of code so you don't have to write this by hand because really it's not complicated logic it is really simple but it takes some time to write correctly okay with that said you can see that we're missing the user right there and the user is just coming from the local storage for example we're getting the user from the form so you can copy that line it is just going to be const user is equal to json.parts local storage get item and then profile finally now that we have that we can put those likes right inside of our like button i'll try to expand it into multiple lines like this we currently have this but now we have the button i'm also going to add a disabled property so if we don't have the currently logged in user i'm going to say disabled and it's going to be disabled if there is no user question mark dot result so if there is no user we cannot press the button okay and now inside of that button we are simply going to have our new component which is called likes this should solve all of our troubles with viewing the likes great let's check it out if i go back you can see we have one like and it seems liked if i click it again it says nothing it just says like it doesn't say zero likes it's not blue you can see it's just outlined and it just says like if i like it and if i log out now and try to sign in as a different person for example i'm gonna go here and go with javascript mastery this time you can see it's one like it's only outlined if i click it it's now two likes so that looks really good it is like facebook has it if more than two people like this i think it's gonna say you and three others or five others or 100 others so this is really good with that said we can move on to the next thing and that is happening right now as we logged in with javascript mastery as you can see we didn't create this post of course we can like it sure but we shouldn't be able to delete it or edit it and now the delete and edit buttons are right here so we have to disable that from happening let's go back to our post and move those buttons away inside of here what we have to do is we have to check if the current post was created from the current user only in that case do we want to show the current delete button so to do that i'm going to open the logic block and then inside of there i'm going to write some parentheses i'm going to check if user question mark dot result question mark dot google id we already had that so we're checking if the id is equal to post question mark dot creator so we're checking if the currently logged in user via google has the same id as the creator of the post or there is a second possibility if the user question mark dot result question mark dot underscore ib if that is equal to post question mark dot creator so now we're checking if the google logged in user or if our manually logged in user is the creator of this post only if that is the case then we want to show the delete button so to do that we can do what we learned and end and then in here we put the button this is going to now appear only if the logged in person is the post creator if we go back let's see if that works and there we go the delete button is now well deleted let's try to do the same thing for the edit remember the edit is hidden right here on the top right if we go back you can essentially just copy this line the line 52 for me now and we're going to put it above our overlay so right here what you have to do is simply close it down here this is also going to make the button for the edit show up only if the creator is the currently logged in user go back and edit button is gone now i'll log out go back in sign in as john wick and let's test it out there we go our delete button is here and our edit button is here that works perfectly if i'm not mistaken to make this app complete there's only one more step that we have to do and that is check if the token has expired right now we are never checking if the token has expired and remember it only lasts for an hour that means that if the user is logged in for more than an hour and he tries to make a certain change like create a post or delete a post or edit it he won't be able to do so in that case we have to check it and we have to log him out so right now i'm going to open the console and the application tab we can clearly see that our user is logged in right now and if we refresh he's still going to be logged in i'm not sure if an hour had passed but let me try to delete this as you saw i just tried to delete a post but nothing happened and if we go to the console well we don't get a lot of information but if we go to our network tab and take a look at a request you can see it is still pending and we don't really have a lot of information on what's going on but if we go to the back end that could give us more info so right now i'm going to open the server and take a look jwt expired that means that we are not allowed to like or delete a post there is going to be a simple way to solve this and that is if token is expired we simply need to log the user out for that we're going to head to our navbar what we have to do is we have to check if the token is expired how can we do that well we first have to check even if the token exists and then if that's the case we want to decode it we can decode a token like this cons decoded token is equal to the code and then we pass in the token that the code is the function that we need to import we need to import it from jwt the code so import the code from jwt the code that way it's going to give us information on when this token is expiring finally we need a simple if check that is going to be if decoded token dot exp that's the expiry multiplied by a thousand is lower than new date and then finally dot get time so we want to get the current time if that is the case we want to log out so if the decoded token that expiry multiplied by thousand this is going to be a certain value in milliseconds if that is lower than newdate.gettime so this is the current time in milliseconds in that case we simply want to call the logout action and that is in this case this function here which is going to dispatch the logout and then push us back if we save that that should be it now considering our john wick was expired or his token was as soon as we came back to the page we were signed out on the signed out users as you can see we have nothing we cannot even like them and we also don't have a delete or edit button now if you go ahead and try to sign in as a different user for example javascript mastery there we go we can like it but we cannot delete or edit and let me try to create one new post let's do something like mern 3 is now out you guys have been requesting this video for so long and now it's out i'm going to say awesome tutorial and tags is going to be auth and all auth something like that there we go so let's choose an image we can also choose fireworks and submit it there we go as you can see we can edit it we can delete it we can like it yeah you can like your own post nobody's saying you should do that but you can and finally if we log out now and sign in with a different person like john wick there we go we have this different pose that can be only liked but cannot be deleted or edited and that is it with that step we brought our mirn application to the end of course this is a complete social media project and we can keep building it as long as you guys want make sure to like and comment all three parts of the current series and i'll definitely do more now let's go on to the last part of this video and that is going to be deployment how are we going to deploy this project in this video we're going to do a really robust and a great production level deployment for that we'll be using zit the link for zeed is going to be down in the description so make sure to click it and then come to here the first thing that you can do is you can log in via github and now in here you'll be able to add one free trial project in our case we have a mern application and mern application is going to be divided into three different things the frontend the backend and the database so let's start with deploying the frontend part you can choose a new project from github you'll have to authorize it and you can search for mern memories of course don't forget to push all the changes that you've made in your application i'm going to click continue and in here i'm going to say something like memories frontend there we go deploy it in here it's going to ask you what kind of project do you have this is going to be a node static site with react and then finally in this case it's not going to be simply npm install it is going to be cd dot slash client because we first have to move to the client then end end npm install and finally and end npm run build we are working with a full stack project so make sure to first navigate to client and then installed and build finally in here static output path is going to be dot slash client slash build once you save this that is going to be it it's going to take a minute or two to build the whole project for production but after that you should get a link that's going to be deployed online for everybody to see and there we go our project is deployed now we can go to the dashboard and take a look we have a deployed project and here's the link to visit it memories frontend dot z app i deployed the version one so in here we don't have the sign up but if you pushed everything correctly to the github you should have access to the latest code of course with zit it's really easy to change the branch the only thing you have to do is in here deploy the branch part three in my case right now we have only branch one and two okay so we have our front end deployed but now we have to deploy our database and our back end the process is going to be the same but the thing is with zit you have one project completely free and we use that one for the front end so if you want to use it you'll have to upgrade your account to the professional one and that one is five bucks per project so definitely if you want to deploy more projects or if this is for professional environment it's better to go with seed they have a really robust architecture and you can deploy absolutely everything on one side with a few clicks rather than going to a few places to deploy the back end and front end separately i completely understand that it's not going to be possible for everybody to have multiple projects with zeed if that's the case feel free to watch the end of the part 2 there i show you how to do really a minimal deployment using netlify and heroku it's not as good as this one but i hope it helps now for everybody who does decide to go with z i'm going to show you how to finish it up you can click new project right here and let's select one new one this one is going to be a docker image we can do something like right here and this is going to be memories longo in here you can choose your database username like javascript mastery for example and we can choose a password i'm gonna go with one two three one two three one two three not as secure but this is just a demo project finally we can deploy it okay our database is already deployed that is great now let's deploy our back end for that we can go to a new project and to github in here you can again choose the project learn memories and in here i'm going to say memories back-end okay this is going to be a unique name so you're going to have to go with something different i'm going to deploy it and then in here we'll have to choose our configuration for the back end for the backend in here i'm going to choose the node 14 version the build command is going to be cd server and then npm install and finally the run command is going to be cd server and and node index.js with that we can save it okay while our back in this building you can click the back end go to the settings and then you can copy this end point right here for me it is the memories backend zit app with that you can go back to your application and navigate to the index.js of the api on the client side in here you'll simply have to paste this url right here of course you need to add the https and then forward slash forward slash right here this is the change that we need to make on the front end and then going to the back end we'll have to change our index.js of the backend inside of here we need to change this connection url because it is going to be just a bit different what you can do is first of all remove this plus srv in here you have to put the username of your database if i go check it out with the memories and to settings i went with javascript mastery and the password is one two three one two three so if we go back in here this is going to be javascript mastery and the password is going to be one two three one two three one two three finally we have to change this url and that is going to be changed to your databases url again if you go back you can find it right here on the memories project and then overview you can see private endpoint is memories production for you it might be a bit different finally you can paste that in here and the last name is the name of the database you can call it something like memories and this is going to be it we change the backend and we change the front-end to match the name of our back-end as you can see memories back and z'd and the last thing in here memories back and seed one final thing that you have to do is finally do git add git commit get push in this case i'm going to guide you to the process of deploying it just to be 100 sure it works i am on branch part 1 and part 2 and i'm simply going to do git add i'm on branch part 1 and 2 on the root of the folder so project memories i have the client and the server both in here and i'm gonna do git add don't worry about this we can do git commit and then in here i'm gonna leave a message for myself delete this commit because i don't wanna leave this for you guys in part one and two in here we should see no different code it should be as it were before you started the video all the changes for the third part are in the branch part three okay and finally we need to do git push that's going to push all the changes great so now that is pushed and let's see in our browser if the changes will apply and there we go as you can see zied automatically started building those projects for react apps it takes a bit longer because it has to actually build it out for production and then deploy it but in a minute or two hopefully we'll see our changes and there we go everything is deployed just to make sure that it works for all of you i'm going to go through some of the most common issues that people have first of all go to the backend part settings and then in here change the port to 5000 one other thing that can be the issue in the code more specifically in the connection url you can change this last part forward slash something you can change it to forward slash admin admin is the default database created for you by so this is going to work in most cases one other thing if a simple password like one two three one two three doesn't work you can switch it to something more complex and make sure to change it in z as well so you can do that if you head to mongodb and then in here settings you can change the password with all that said our project is now deployed let's take a look at it of course to take a look at the finished product you can head to the front end part of this project there we go we are in here i just created this test post but everything seems to be working fine let's try creating a few other posts i'm gonna do test one test one test one and again an image right here there we go this works you can add you can delete the post everything works perfectly besides one thing and that is the login and authentication using google if you try clicking that you'll be able to see that it says redirect uri mismatch this is not a problem that we've made we just have to make sure to add this new url to the google credentials to do that you can again head to console.developers.google.com and then to credentials the link is going to be in the description inside of here you can click the memories app and now we have to add that new endpoint of our application no longer is this going to be localhost 3000 now we have the memories front-end z app so right now i'm going to add the uri and it's going to be just this and for the redirect uris i'm going to add the same one and i'm going to also add the same one with the forward slash auth now if we save that our app should be working fine google sign in and right here there we go we are logged in if it didn't work right away for you make sure to do that trick where you delete the cache and delete all the memory from the browser there is going to be a link to the description of the stack overflow solution down below so you can also check that out but with that said this works completely our application is now deployed using zeed we have this url that you can send to absolutely anyone and all of our projects are deployed on the same site the front end the back end and mongodb that is truly revolutionary and the thing is you really cannot notice how robust the zit is because of their simplicity the ui itself is extremely simple and user friendly but their systems are really robust with that said if you had any issues with the deployment make sure to contact chad right here you can click this bubble icon in the bottom right the theme will quickly get back to you with that said we are at the end of the third part of the memories project it was definitely a long ride but it doesn't have to end yet if you'd like to see a part 4 where we make this better even further feel free to let me know what features would you like me to add that's going to be it for this video thank you so much for watching and see you in the next one [Music] you
Info
Channel: JavaScript Mastery
Views: 970,768
Rating: undefined out of 5
Keywords: mern stack, mern stack tutorial, mongodb tutorial, react full stack, mern stack project, mern stack tutorial 2020, mern tutorial, react node express mongodb, mern stack traversy, mern stack full project, mern stack tutorial for beginners, mern stack tutorial step by step, mern application, mern app, full stack mern application, mern application example, mern authentication, mern authentication tutorial, mern authentication jwt, google oauth, google oauth 2.0 tutorial
Id: LKlO8vLvUao
Channel Id: undefined
Length: 163min 32sec (9812 seconds)
Published: Fri Jan 15 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.