What are JSON Web Tokens? JWT Auth Explained [Tutorial]

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and welcome to this tutorial I've actually added this part after I finished the tutorial course I realize you may be completely beginner at JSON web tokens and I didn't talk anything about what a JWT token is so I'm going to do that shortly before we start creating stuff in this tutorial I recommend you to check out JWT dot io / introduction on that page they'll describe everything that you need to know about JSON web tokens and we can check out the first part here what is JSON web token JSON web token is an open standard that defines the compact self-contained way for securely transmitting information between parties as a JSON object so that's what we're going to do we're going to build this in our application and send along a JSON web token and that is a JSON object and also this information can be verified and trusted because it is digitally signed and the token can be signed using a secret or you can encrypt it we are going to use a secret meaning that on our server part we are going to have a secret that will sign or JSON web tokens with so a JSON web token is a JSON object that we can use to transmit information between our server and or application in the client and you can also read down below here they tell you why you should use it and when you should use it in our case we're going to use it for authentication and authorization and I think yes they say this is the most common use case because when using a JWT token we don't have to send along or login and password on each request we can just send the token and the token can guarantee that it's the correct user that sends the request so that's the main advantage of using a token we don't have to send along the login and the password on each request we can just send along the token and we will know that the user is legit and they also mention that the overhead is small and it has the ability to be easily used across different domains so that's the main advantages of using a JW token in your authentication and authorization system so in our case we're building this very lightweight server and from this server we're also going to generate this token and send it along to the and when the user logs in all right we can continue to scroll down here they also describe what parts there is in a JSON web token and you have a header of payload and the signature and here is how it looks first you have the header then you have a dot and on the payload a dot and a signature so the header will mostly contain data about that this is a JWT and also the signing algorithm for the token and then we have our payload we can send along what we want here in our case we're going to send the user and we're going to have the email address in this very very basic example that we're going to build so the user can log in and we send along the email address to the client so the email is going to be the username in our case but you can put some other data here also of course in this case I think they yeah they have the name and I have if this one is admin and other stuff here okay and then we have the last part that's the signature now we're going to sign or token with a secret that we set on our server that way we know that this token is guaranteed to be generated from our server because we're always going to verify that it's signed correctly all right so I think that's about it that's a very short introduction to JWT tokens and we can get started to create our application and our server I'm going to talk a little about JSON web tokens and how you can authenticate your application with refresh tokens and access tokens Andrus actually a few good tutorials out there but they are using a lot of stuff that you don't need to understand the concept of JSON web tokens so my take on this is that I create a very simple Express server where we set up our endpoints just regular rest endpoints and I won't even use a database we're just going to use a fake database object for this one so we won't persist the data cause you don't need it if you just learning the basics all right so nothing fancy in the server in the backend and I'm just going to use react for the front-end and when you're going to fetch the endpoints with no external library or anything like that so hopefully this will be a good way for you to learn about JSON web token if you're new to the subject and horse I will say this that I'm not a security expert I'm mostly front-end developer but I do some back-end stuff also so this is not in any way any code you should use in production and the code may also be a little bit verbose because I want to show you all the details on how this work my main goal with this tutorial is to show you how the JSON web token flow works between the server and your application and how you can use it it's not to create a very secure API that you can use in production alright so let's get started first of all create the folder of your choice I call mine JWT oath and inside of this we're going to create another folder that's called server we're going to have two folders for this one one is the server and one is for the front so first we set up all the roads all the restaurant points for us that we can use in our application all right and we are going to use Express for this one first we have to type NPM in it to the Creator project and it will give us some defaults here this one we'll call it JWT oath and that's fine version is one description you can have a description here if you want API server or entry point it's going to be the index das file so that's fine and test c'mon we're not going to do any tests here and get repository non keywords none you can just press ENTER here is this okay yes enter all right so it's created a package.json file for us and let's go inside our code editor now we can have a look at that file and as you can see it created this stuff for us here alright then we have to install some packages we're just going to use Express but there's some packages that are going to help us in the creation of our API so we are going to install something that's called bcrypt j/s and with this one we can hash or password because you don't want to store your password in the database or in our case a fake database we have to hash it and also sort it you can read about bcrypt at this page here or you can yeah I'm not going to go through it in detail here then we're going to install something that's called cookie parser and this will help us to get the cookies from the request so what it will do is to create an object that's called cookies where we just can grab our cookie that we're going to use for the Refresh token then we're going to install a package that's called course because we don't want to have any cross-origin issues here so we're going to install this and configure it I am going to use environmental variables for this one so we install the package dot m and I'm going to show you this in a second and of course we have expressed that we're going to use and then we're going to create JSON web tokens so we have a package for this also and lastly we are going to use something that's called node mom and this one will yeah it will make our development a little bit easier because it will restore the node server as soon as we make any changes and we don't have to do that self manually okay and I'm using postman to test around points it's free so I think postman is very good to use for this all right so let's get back into our terminal and install these packages so we type NPM I and we have bcrypt yes we have our cookie - parser we have our course or dot n and we have Express we have a JSON web token and a node 1 is actually going to be a dev dependencies who install that one after this one okay let's take a look inside our code it install here as we can see that's good and the node mung we just install it like a dev dependency here so we have NPM I knowed mom - - save - dev and it will install it for us as a dev dependency okay you can see that it added it here as a dev dependency and that's great so that's all that we need for this API to work and we're going to start coding it now first we can create a new file that we call dot n because we're going to create some environmental variables here and the first one is going to be called access underscore token underscore secret and it's going to equal you can select whatever you want here I will of course use Velen rules yeah okay maybe I should spell this correctly also to see sin access okay then we have a refresh on the score token underscore secret and this one is going to be wave and rules even more and then we have the port it's going to be on port 4,000 all right so we just save this one then we're going to create a new folder here that we call SRC and inside of the SRC we can create a new file that's called index dot yay okay so we're going to start importing some stuff here first of all we're going to require dot and forward slash config and this one will make sure that we can use the environmental variables here then we create the cost named Express and we require Express we are not using es6 imports here because this is node and this is the standard as you do it in node you can do it with es6 imports if you install some packages but we're not going to do that here so we import Express then we have our cookie parser require cookie - parser we have our course and we have our verify that we're going to grab from a JSON web token library and make sure you have these curly braces here because we're just importing the verify from that one then we're going to grab hash and compare require bcrypt j/s right so that's all what we need for now we're going to do a little bit more imports here later on when we create more files and stuff here so what are we going to do now we have a few steps here one we're going to create an end point where we can register user two we're going to have an end point for login the user three we also want to be able to logout the user for we're going to set or protected roads and five get the new access token with a refresh token and of course you should have something that you can revoke the Refresh tokens with but I'm not going to go through that in this tutorial because I want to focus on the most basic stuff here just to show you how Jason web tokens work okay first we create our Express server Const server equals Express that's the one we imported up here so that will create the server for us and then we want to use Express middleware for easier cookie handling so server dot use and we call our cookie parser and this will make sure that we can handle the cookies a lot more easier then we're going to set up our course because we don't want to have issues with that later server dot use and we have a course that it's going to take in an object we have an Origin HTTP colon forward slash forward slash localhost and we are going to have our front end on for 3000 what we're going to use create react app and that one is default port 3000 then we're going to set the credentials to true okay so this will make sure that our frohnen and/or server can communicate with each other then we need to have a couple of rows here so we can read our body data and we can actually type out the comment here needed to be able to read body data okay grab a server and use and from or Express we can just call Express JSON like this and this will make sure that we support JSON encoded bodies I can make a quick comment here also to support JSON and and coded bodies then server dot use from Express yet again this is built-in Express view RL encoded for this one we send in an object with extended assert that wanted true and this one supports URL encoded Boris right so this is our configuration for our Express server and we can actually get it up and running also and then we're going to create our endpoints and to get it up and running we can just serve a dot listen and from our process dot and we have our environmental variable called port inside of here so we just grab this one with this now we have an inline error function here and we can just console log out something here server listening on port this is a template literals we can just grab process dot m dot port and we end it with not a back T and I should of course removed this one you can save it and then go inside or a terminal here it I actually don't have a start script for this one so we can create this one also let's go back inside of our package JSON file and where you see this property named squits we can create another one here that's called start and we are using node moon for this one as I said this one is going to make sure that we don't have to restore the server every time we change something in our code so we just call or in dot J's file here and this is an object so make sure you have a coma deer also so we say this one go back inside our terminal and type M film start and as you can see it's starting up or so over here and that's good so we know that it's working and then we can create our endpoints and I'm actually going to go through this quite fast because I think this course is more focused on a front-end developer that want to learn about JSON web tokens and not how to create the backend itself but I have to create it here to be able to show you how the JSON web token and the flow between the front-end and the server will work so that's why I created back in here also and you probably will learn something about it even if you're not a back-end developer at all so back into our code and inside our index dot K is file so first of all we're going to create an endpoint for register user so we have a server and this is going to be a post request are we going to have register in our endpoint URL so it's basically going to be our server that's localhost and then forward slash register for this endpoint this one is going to be async we have our request and our response and we're going to send in the email and the password with the body so we can grab these ones from the body with the structure them out email and password from the request body and we have to do a few things here now we're going to type our code inside our try block and then we have our catch that is going to catch the error for us so inside over here we're going to do a lot of stuff first we're going to check if the user exists and we're going to do that from our faith database but I want to populate the fake database with a user so I'm going to need a hashed passed for that one so that's why I'm going to create a hash password and console.log it out and then I can just copy and paste it inside of my fake database that I'm going to create so Const hash password we await hash and we have our password that's the one we got up here and we going to sort it and this is how many times you want to calculate the salt so I think ten times maybe something like that so this will give us a hash password and we can console log this out and save it and to start up the server again and I'm going to go inside of postman now and use that one so I have this endpoint that's called register and I actually have it appear on our local host and port 4000 we have the register endpoint and I've attached an email and a password to the body so well send this one hopefully it will come so log out perhaps password for us and it did so I'm just going to grab this one from the console copy it go back inside of my code create a new file inside of the source folder here and call it fake dbaas then I'm going to export fake DB and it's going to be an array that's going to have different objects with the different users so we create an object we set the ID to zero the email is going to be my mail you can of course use your own here like this and then we have the password and inside of the string are just pasting in this password can also make a note here the password is test so this is a fake database that we're going to use sale is one can go back inside over index.js file and we can finish this register and point so first of all we're going to check if the user exists Combs user from the fake DB of course we also have to import it up here so Const fake DB equals require now we grab it from dot forward slash fake DB dot J s ok in our fake DB this is just an array so you can just use the array method find and we have our user we check if our user email equals or email so we check if this email exists in our database and this one here is the one that we got from the body and of course in the real world here you should do some connection to real database and check for that there so this is a fake DB this is just an array with JavaScript objects but you're going to use a real database here in the real world in production but for now this will do for us okay then if we have a user we're actually going to throw an error here because if we user exists we shouldn't be able to register a new user with the same email so we throw new error user already exists if not user exists hash the password and we've already done that here so you don't have to do that again we have it stored in the hash password Const so three insert the user in and I'm going to put this inside of quotes because this is not a database this is just a fake database but you insert the user in your database and we can just push the user inside the fake DB array fake DB push we create an object we have an ID fake DB dot length the length is always going to be larger than the index so that's why we can use the length here because if we have one post in our database as we have now this is the index 0 but the length is going to be 1 so that's why we can use the length here then we have our email and we have our password and this one is going to be the hashed password and we have a coma dear of course okay so we have stored the user in the database so we can send back a response to the client rest sound and we have an object with a message of user-created life so instead of console log out the hash password here we can actually console log out the fake DB all right then we also have to catch if we have some arrows so we send back the response with an error and we just send the error message error dot message all right and do a little bit of order formatting there so this should be it for the register endpoint so we try it out in postman and I created this once no so I have to actually kill the server now I start it again because I want to clean up my fake database so I go back in postman I put the email and the password in the body that's my email address with a three and was to the test as password so I send this one used to create it that's great and as you can see we are console logging out the database we have two uses here now and that's great go back inside of postman and try to register the exact same user and it tells me that the user already exists and that's great so we can't register the same user twice so we know that it's working that's a register endpoint now we're going to create our login endpoint yeah and I should of course move this one to the bottom like this login a user right yet again we have a server dot post we create a post request and it's going to be log in we have an async inline function here we have the request and the response and on error function and yet again from our body we want to grab our email and our password so we destructor them out from our request stop body then we have a try and the catch with the error like so and inside the try block we're going to type out our code so first find user in array or in or in database if not exist some error right Const user fake DB not find this is the exact same step as we did before so just check if the user email equals the email and now check if not you sir if we don't have a user throw new error user does not exist right so if we don't have a user we cannot login to compare cryptid password and see if it checks out some error if not so create cause that's called valid we have wait and we have this compare function from the bcrypt library 3 compare or password that's the one we got up here from the body and now we have a password stored in our database from the user of password so we compare these two and see if they are the same so if not valid throw new error password not correct so if it not checks out we just send an error and tell the user that the password is wrong but if it's correct we can create a refresh and access token like this and the ID today is to have a refresh token and an access token your access token should have a really short lifetime and the Refresh token should have a longer lifetime and stored for example as a protected cookie that you cannot use from inside of the JavaScript in your client we're going to create two tokens 1 refresh and 1 access token first we have our access token am I going to have to create this somehow and we have a refresh token that we also need to create somehow and we're actually going to create a new file here just call it tokens dot yes and inside of this file we first import sign require we require it from JSON web token then we create the function here create access token we're going to send in the user ID as a parameter and from this one we're going to return something and we're going to return sign we call that sign that we imported up here we give it an object with the user ID and then from our process dot on dot access underscore token secret so we sign it with that secret and we also include our user ID then we have an object where we could set the expire time expires in and for this one we're going to set the 15 minutes so this is how we create the access token we can just copy this one and paste it in and we can rename it to create refresh token and we change this one to refresh underscore token underscore secret and it expires in seven days that's a week okay and for now we just module export and we export our trade access token and or create refresh token so we can use them in our index.js file so of course we have to import them up here at the top first Const create access token and create refresh token require and it's going to be from dot forward slash tokens IAS all right we're good to go we can use these ones inside of this file now so first we create an access token great access token with sending the user dot ID that's the one that we got from the database and here we create the refresh token and we also send in the user dot ID and in the real world in the real life you could also create different versions of the refresh token and store it in your database or just store a version number if you don't want to store the complete refresh token and you can compare it you can sign it as we do here you can also sign it here with the test access token the refresh token you can have a version number here and then you can check the version number and when you revoke the refresh token you just increase the version number and that way that token could never be used again but for the sake of the simplicity of this tutorial I'm not going to do anything of this I've just created one refresh token so if you want to make some function to revoke it you just can delete this one from the fake DB but keep in mind that you can have different versions of refresh tokens so for now put the refresh token in the database and we already have our user here so we can just mutate this one we create a new property that's called refresh token and we just give it to refresh token so we save that one inside of the database there and if we want we can also console.log out the fake DB here so we can see that this actually gets created alright so we have our access token and a refresh token created that we have to send them to the client somehow it's a five-cent token refresh token acid cookie and access token as a regular response right and we're going back inside over Tokyo's jeaious because I'm going to create two functions for us that is going to handle the sound of the tokens so just below here we create another function send access token now we have the response to request and the access token and we just do a response sound you could of course do this inside of the index file also but I've did this too yeah kind of structure it a little bit so we send the access token and we can also yeah we can send the email also from the request body dot email right and then we have a Const sound refresh token for this one we're going to have the response and the token we can call it refresh token all right and for this one we're setting a cookie instead we don't want to send it with a regular response so we our rest cookie we're going to call the cookie refresh token you can of course call it something more secret because now you can just check the cookie and see that this is a refresh token but I do it like this so we easily can track this token that's why then we have our token and we have an object we're going to set it to HTTP only and this make sure that we can't access this cookie from our client you can't modify the cookie with JavaScript and we're also going to set a path because we don't want to send this cookie along with each request we just do it when we're on the refresh on this Court opium endpoint this is the end point we're going to use when we want to get a new access token with or refresh token and I'm going to come back to that later all right we also have to export this once send access token and send refresh token like this so that's all for our tokens dot J's file let's go back inside of index dot JSON user function here of course we first have to import them up here so we import send access token and send refresh token all right now we can go back inside of this one here yes below here we first send a refresh token we have the response and refresh token itself and then we call send access token we have the rest once the request and the access token maybe this should be the other way around here maybe have to request first on the response as the second parameter but yeah hey it's like this now okay all right so that's it we just have to catch any errors if we get that here so we're rests and just as we did before we have an object and an error message back ticks it's a template literal we grab the error message and end it with a back tick like this all of you married and save it so we can go back inside of postman and we can try to log in here as you can see in the body I send the email and the password so we try to send it okay we have some error here create access token is not a function all right yeah I know what it should be exports here not export so make sure you have an S there also if you also miss that one save it and go back inside of postman and we try this again now we have another error here token is not defined all right yeah of course I rename this one here inside of tokyo's yes it should be refresh token and save this one I actually called it token first but I changed it now when I record this to refresh token cuz it makes more sense so it should be refresh token and back again inside of postman we try it again and as you can see we get an access token back and we also get our email back and did we get something inside of the database yeah you can see icon so logged out the database here and the Refresh token has been created and it's now in the database so we can try to register a new user here I have this one with a three in my email so I just create a user and as you can see one is created but it don't have a refresh token no we haven't logged in and got the Refresh token so it seems to be working now that's great so let's get on with it we also want to be able to log out the user 3 log out a user this one is going to be C we have the server dot post and we're going to have log out as the endpoint we have the request will not continues that one so I mark it with this underscore and we have the response so when we log out we just clear the cookie rest clear cookie and we call it refresh token that will make sure that we wipe out the Refresh token from the cookie and we also have to clear the access token from the client of course when we log out but with no refresh token we can't get a new access token before we login and then we just return the response not send and a message logged out that's or log out then number 4 we are going to create a protected route just to show you an example of how you can do this authorization with the token so we have served on post we can just call it forward slash protected this is an async function so we mark it with async and we have the request the response and an inline error function then we try we catch the error now we have a Const user ID is off now we send in the request we are going to create this one now so we create a new file inside of this source that's the last file we're going to create here we call it is oath doc yes and first we are going to import verify we require it from JSON web token and that's the way we can verify the token that we have in our header then we create the function called is auth we have the request an error function Const authorization and from our request and the headers we are going to grab the one that's called authorization and this will give us our token if we don't have any token if not authorization then we throw new error you need to login because if we're not sending a token we know that the user isn't logged in so that's why we can throw this error and tell them that they need to login otherwise we can get the token so from authorization we split that one like this and we grab from index one in the array and this is because the authorization in the header is going to look something like this beer and then you have the token in here this is a string so we just strip out beer and we just grab this one and that's what we're doing here so that's how we get to token so this is a standard as you use beer and then have the token after that word that's called beer err yeah that's very difficult for me to say because I'm not used to that smooth ours are are yeah you know it's it's tough to be from Sweden and try to speak English alright so we have our tokens then we're going to grab our user ID and we get it from verified and that's from JSON web token we have our token and we verify it with the process dot M not access underscore token secret so this way we make sure that this is a legit token and then we just return the user ID okay module dot exports equals is oath or you could of course just export it as we did with the fake DB exports dot faith DB instead if you want to do that right back inside of index we need to import is oath Const is off equals required dot forward slash is oath yes and now we can use it here this is getting a little bit messy here I I know that as I said the code is going to be a bit verbose and there's a lot of code here maybe but I think it's necessary to fully understand something when explaining advanced stuff like this if the user ID doesn't equal no and that's because we could just do it like this but that will give us a false answer if the ID is zero so that's why I'm doing this we have rests and the data you can just type this is protected data all right and then inside of catch just as before rests and we send an error message like so so we save this one and we can see if the protected route works then login again protected and as you can see in the author sation here we can just grab the access token that we get here and this is actually an old token also it shouldn't work now it says that you need to login so if I just paste in a new token here it hopefully should work and it doesn't all right yeah and of course I can see now I forgot an S here it should be headers it's very easy to forget something like that so I save it and then we can try it again yes you can see this is protected data so now we're accessing it with our token and that's great really really easy to do something stupid like this and forget on s I hope you didn't do that that's the second time in this tutorial I did something like this right I have to slap myself in the face cuz I'm not bad at typing this stuff out right back inside of index we know that this one is working and we just have one more route to create and then our API will be finished and that's the route for getting a new access token so 5 get a new access token with a refresh token all right we have server dot post forward slash refresh underscore token we have our requests and our response and an inline error function we have our token and now we can just grab it from the request cookies refresh token that's why we install the library that's called cookie parser and if we don't have a token in our request if not token return response dot Sam the access token we just clear it out so we just send an empty access token you could also send a message here also to the kind of course otherwise we have a token let's verify it so we left we create payload and we set that one to node for starters and we have a try and the catch with the error inside our try we set the payload we're going to verify we have the token that's the one that we grabbed from the cookies and we have our process dot m dot refresh token refresh underscore token underscore secret we verify that our token is legit otherwise return response dots and yet again we just send an empty access token we know that the token is valid so check if user exists Const user we go inside or fake DB and find user we check if our user ID equals to the payload ID the payload user ID because we signed or token with the user ID we get that one when we verify it if this verify it will give us the ID so we can just compare this one with one in the database and see if it exists there the lid it should say if not user returned response and yet again we send an empty access token because the user didn't exist in the database user exists check if refresh token exists on you sir if you sir got refresh token not equals token if we have another token registered to the user we don't want to send a new access token so we just return response and have a set access token to an empty string again whoa there's many steps here where will token exist create new refresh and access token so again we create our access token create access token sundean or user ID as you can see here this is repetitive code we did this up here before so as I told you before this code is very verbose you can refactor it to make it more effective and look a lot more cleaner but it's good to have it here now so easily can understand every step and how this works then we create the refresh token also with the user dot ID then we need to update the refresh token in the database and as I also told you before you could have different versions here instead of the Refresh token but I will just grab the user and refresh token and mutate this property here with a new refresh token so this will update it in our temporary database object all good to go send new refresh token and access token so we send the Refresh token we have the response and the refresh token and then we return rest and and the access token whoa that was a lot but hopefully you'll understand all the steps needed here and you can also see that you need to have some connection to a real database and uses that you saved somewhere because this is just fake so let's save this one see if it works no errors that's good we can try this out now first of all we can log in we have the refresh token so we try this and as you can see we get a new access token back that's because our refresh token is saved in is saved in the cookies I think we should be able to see it somewhere yeah here you can see the refresh token that is being sent but we won't be able to grab it in or JavaScript from the client and then if we log out like this we shouldn't be able to get a new access token obviously it has not cleared it from here yeah and I think I know what's wrong we have to set the path here also it has to have the same path refresh on the score token like this because we told it to just send this cookie on this path so when we clear it we just make sure to include this path here also so I save this one and go back inside of postman and hopefully this will work now I'll log out yeah and as you can see it won't give us an access token now and then we can also try out we try to login then a new cookie should be set so icarly is right again and as you can see we get a new access token so it's working now make sure that you include path here otherwise it won't work all right so that concludes the server in the next part we're going to create the front-end with react and use this API hey this is the second part in this tutorial and we're going to build a frog on in this one and as you can see I'm inside a JWT oath folder now that I created in the last part and I also have this server folder and I hope you didn't made the same mistake as I did because I didn't navigate inside of this folder when I created API so I had to move all the files manually inside of the server folder so i navigate inside of that one and all our files are here for the api and also we can open up the code it can always be good to have it here if there's something that we need to change in our api and actually I had this typo again I had forgotten I in the origin in the course in the index doc jeaious file hope you didn't do that mistake also so make sure that it says origin here otherwise it won't work okay so back inside of the terminal we can just mm start them fire up our server then I have another tab here in my console and I'm going to create a react application for a front-end now I assume that you know react I'm not going to teach you react or CSS or anything in this course I'm just going to very quickly create this little application that we can use to communicate with our server to get our JSON web tokens and show you how JSON web tokens work alright we're going to create this application with create react app so we type MPX create - react - app and we're going to call it from them and this will create a folder here that's called frohnen and it's going to put all the code inside of that one so just have to wait a little bit now so that's it we navigate inside the front-end folder and open up our code editor so this what we've got here we have a package.json it's installed everything for us and we also have this SRC folder with different components that it's created for us and we can actually remove some of them here we can remove the service worker we can remove the logo you can remove the app test and the app dot CSS we're going to create some CSS in this index dot CSS file and we also have to go inside index J s so we remove the serviceworker and remove all this stuff here and just save it and inside our FJ s remove the app dot CSS import and the import of the logo and for now we can just remove everything on this and let's type out app and then we can go back inside our console now we're going to install two dependencies so npm i we're going to need the reach router for this one at reach forward slash router and also i think we're going to need a es lint - plugin - react - cooks and while this installs i can grab some coffee here that's always a good idea and as you can see I'm getting this errors here they started to appear just recently I think it is because I'm using both yarn and NPM they create react app create the app with yarn and now I'm using NPM but I'm going to show you how to get rid of these if you get these errors - just wait for it to finish here so what you can do is you go inside of your code just remove the node modules folder and also the package lock file and go in terminal and thought mmm install I haven't got time enough to dive deep in this and see what's causing this so I don't really know actually but I know that this works so that's it we can try and perm start and we navigate to localhost 3000 and as you can see we're showing up here so we know that it's working that's good so back inside our code editor and we're going to create a new folder here inside our SRC folder create a new folder named components and we're going to scaffold out five components we have one that's called content doc yes one that's called login DoDEA's and navigation doc yes protected doctor yes and register yes we can just careful out them now and we'll come back to them later so we import react from reacts we create a functional component called content equals and an error function and for now we just return a div that says content and we export default content all right we can just copy this one now make sure you save it also of course and go inside the login and we change this content to login and save it move on to the navigation change content to navigation save it and inside protected the same thing protected and register register so this is just the scaffolding of this we'll come back to them later and I can also say that this application will also be a bit verbose in the code and has a maybe a lot of redundant code for example the login and the register component will have almost the same code inside of them that's actually intentionally because I think that I will make this as easy as possible for you but this is not in any way just as with the API of production finished application we just training it in educational purpose so bear with me with that one okay and we have to create some CSS for this one also so we can do that right now when we are added so inside of the index dot CSS file we have this body we can actually remove this code and up here we can add the background and it's going to be still blue just keep everything else here doesn't really matter then we have the dot F class and with text a line we set at the center we set a min height of 100 viewport height we display flex we set the Flex Direction to column we align items Center and also justify content to Center we set the color to white FFF and the font size to 16 pixels okay then we have a class that's called login - wrapper we set the mean height to 200 pixels we set the mean width to 300 pixels we set the background to white the parent to 20 pixels the border - - five pixels and light blue and solid we set the color to black zero zero zero okay that's our login wrapper and we are of course going to use these classes in our components in a production app I would use style components but in this case we're just importing a regular CSS file and yeah that's not good to do it like that but it it'll work for us in this application then we have dot log in - input and we're going to have a button in that one so we set the background on the button to light blue we display:block we set the width to hundred percent the heart 250 pixels yeah and that's it for that one then on the same class login - input we're going to have our input fields and we can display block we set the padding to 20 pixels the width is going to be hundred-percent the height is going to be 50 pixels and Morgan 10 pixels 0 we set the box icing to border-box okay just a few more we have to start or unordered list that we're going to have for our navigation so we have our ul list - style - type we set at one to none except Morgan to 40 pixels auto we set the width to 300 pixels and the padding to zero then we have the UL li elements we display inline - block and set the Morgan to 10 pixels right on the last one and that's the link that's the a tag we set the color to white FFF and text-decoration:none so that's our CSS and we can already see that it's changing here and that's good okay we can move inside our FPS file now and we're going to create this one first we're going to add some imports here we're going to use state and also use effect for this one and then we import router and navigate from at reach router okay then we import all our components so we import navigation from dot forward slash components forward slash navigation we can just copy this one paste it in four times we change these ones here this one is going to be the login this one register protected as you can see I'm changing it in two places at the same time here so make sure you also change the path here and the last one is going to be her content all right so that's our component then we're going to create a context that we're going to use for yeah almost like a global state here by creating a context we can access the state inside of all our components in the application so we export Chrome's user context and react dot create context and for now it can just be an empty array so that is going to be our context and inside our app components we are going to create some local state first we have a Const with our user and set user that is going to hold our access token so you stayed and it's going to be an empty object for now let me create another one loading and set loading and you stay and we set that one to true because when this application run we're going to have a use effect that will fire off and send or refreshed opium to get a new access token if we have a refresh token so that way we don't have to login yeah in a production app you wouldn't do it this way you probably will have a library for example a polar or something that will handle this for you when you have a real database to connect to but for now to this tutorial as I said I will do this as simple as possible so we're just using the thing we got in react and we're going to grab it with the use effect we're also going to have a couple of functions in this one so we have const log out fullback and this one is obviously going to be for our log out button and it's going to be a sync and we leave it empty for now then we're going to have our use effect and that one is also going to be empty for now to give it an empty array here also as a dependency so then we can create our JSX for this one so we have this div with the class name of app we're going to wrap it with our context so we have our use of context dot provider and the value is going to be on array with our user and set user so this is the way we can pass this state down to all our components you close it remove this one inside of that one alright then we have our app then we're going to have our navigation the navigation is going to have a logout callback logout callback so this is a prop so we send in our logout callback function so that one then we're going router we're going to change routes here depending on what page you're on so we have an ID of router and then we just have our components here we have a login component that's going to have a past of login then we have our register that's going to have a path of register and or protected that has the path of protected oops it should self closed like this and then we have our content and this one is going to have the path of a forward slash because that's our main landing page that's our homepage and I think this is it for this component actually for now of course we're going to fill this out with more code later but we can save it and see what we've got so button navigation and content here and that's great so we can actually create our navigation now so make sure your navigate inside of your navigation dot JS file so we're already importing react we're also going to import link from at reach router okay then we got our navigation here we're going to the structure out or prop or logout callback and here we create parentheses and as you can remove this one because you're going to have an unordered list here and then we create our menu items so we have a li element we have a link and it's going to link to the forward slash that's our homepage so we name it home and we can actually copy this one and paste it in three times and this link is going to go to protected and we type our protector and this one is going to go to red stir and register and the last one is not going to have a link actually it can't have a button so we have a button with an onclick handler that's going to be or prop logout callback and we can just type up logout so this is it for a navigation we save this one and see what we've got yeah we have our navigation here and as you can see it changed rocks here and that's good and it also change component here so our navigation is working and or routing is working that's nice okay so we can move on to create our content component so inside the content of J's file up here we also go into import use context that's a hook that we'll use to grab our context then we import a component that's named redirect from at reach router and we also import our user context to grab that from dot dot forward slash and it's in or F right now we have our content component we can remove this one and create curly braces because inside of here we're going to check it for context if our stayed in the context the user contain our access token so we can grab that one first Const user we use context that's the context hook that we imported up here and we send in or use the context and this will give us our user so if we not have a user dot access token we just return and we have the redirect component from the rich rural library from we set that one to an empty string too and we're going to redirect them to the login code if we don't have an access token we want them to login and we don't want to show the content here and we can also have no throw like this otherwise if have an access token we return a div and here we can have our content so this is the contents okay so this is it if you're using something like as I said a polar or something you should have that one to check if the access token has expired or not or and if it has expired you can automatically in the background grab a new access token if you still have a valid refresh token but I won't go through that here I'm not doing that here so if the access token expire it won't grab a new one from the Refresh token endpoint automatically okay we'll save it and we can go to our start page and as you can see it's showing us the login page we don't have an access token so that's why it's redirecting us to the login page and that's great so we can actually create our login page now to make sure you in the login is file up here we're going to import the more stuff from react because the you stayed use context and use effect and we also going to import navigate from a tweet router and we import our user context from dot forward slash app alright and then we have our component here we can remove this one and create color braces first we grab our context comes user and set user equals use context and we send in our user context then we're going to have two local states for this one it's going to be one for the email and one for the password that's the input fields that we're going to have in this one sorry create a Const email and set email you stay and it's going to be an empty string for now and then we have the password and set password equals you stayed and an empty string like so then we're going to two functions in this one we're going to have one that call and I'll submit and it's obviously going to handle the submit of the form it's going to be async and we have the event and an error function and we leave it empty for now then we're going to have one that's called handles change and this one is going to be when we type something in the input boxes and we have the event and an error function for this one also so we can start typing out or JSX that we're going to return for this one so return parentheses we have a div with the class name of login - wrapper we have or form that is going to have an own submit and we just call or handle submit function on that one and inside our form we're going to have our input fields but first we're going to have a div with a header or maybe yeah can actually have an h2 tag that says login and then we have an input it's going to have a value we grab that from our state email this is going to be a control component so unchanged we call our handles change it's going to be the type text' name is going to be emailed the place holder is going to be email and i think we need to have something that's called autocomplete email and we can copy all of this and paste it in below all of these we change the password place or maybe a capital P and this one I think should say parent - password so make sure you change all of these here then we of course need us meet button so below here we create a button type submit' and it can say login yeah yeah we also have to wrap these inputs in a div that's called class name login - input so move this everything here inside of this div something like this the order for Mary isn't working here now for me so I have to do it manually ok we save that one and we can see what we've got so far yeah this one shouldn't be all the way out to the areas I don't know why we look into that later okay so let's get back inside over login dot J's file so first we have these handles change because when we type something here it doesn't show anything now at all so we have to hook this up to our states will show the values so we have these handles change we got the event here so we can just check if the event dot current targets the name equals email then we can set email a dot current targets dot value right we just have two input fields in this one so we can just make an else here we know that otherwise it's the set password we should call a dot current target dot value so we save this one and we can see if it works and as you can see we can type something here now and that's great it works alright then we have our handle submit and this one is going to do all the job for us to grab the token from our API so the first thing have to do inside of here is to prevent the fault we don't want to send the form because we want to handle this ourselves then we have Const result we're going to await and we await again we fetch from HTTP colon forward slash forward slash localhost and our server is at port 4000 and we're going to hit the endpoint login then we have a coma and an object because we need to send in some stuff here also we set the method to post you set credentials to include then we have our headers and our headers is going to be content - type application forward slash JSON all right so we're setting the type of our headers here and then we have our body and that is going to be json dot stringify we have to make it a string and we have our email actually as it's the same here we can just type out email and the same with password and here we have dot JSON we call that one that's why we await two times here first we await the fetch and then we await when we convert it to JSON so that will give us the result in this comes here so if result dot access token if we got an access token we can set the user so we set the access token and we grab that from the result dot access token then when we have set the access token we want to navigate back to the home page else if we don't got an access token we can just console log the result dot error all right and if we want we can also create the use effect here when the users change we create a dependency array with the user and we can just console.log out the user so we see what's change inside of that one alright so we save this one and we can try it out so let's go to our application and inspect I want to look in the console we reload it you can see we have an empty object here to start with because we console log out or use the state or access token state we can try to log in here then you can see we console log out the error here and it tells us that we not sent along a valid password and my password is going to be test and as you can see we got the access token here and now we redirected to the start page and it's showing us the contents so that's good but we're not grabbing a new access token now as you can see here so it will wipe out the state every time we reload this but we'll fix this later so we store the access token in our state in the application we're not storing it in local storage or anything like that we're just having it in our application and the refresh token is being sent to the client as a protected cookie so we can't really do anything with that cookie with our JavaScript code so back inside our code and we can actually go inside of the app dot J's file and in or use effect here I can make some comment first thing get a new access token if a refresh token exists right so inside a reduce effect we're going to create an async function refresh token so we get the enhanced result and we await and we await again fetch and this time we're going to hit our endpoint for a refresh token so localhost port four thousand four slash refresh underscore token coma and we have an object here method post credentials this one has to be include otherwise the cookie won't be included and it won't work so needed to include the cookie we have our headers we set the content type to application /j so I actually think that this is the default but it won't hurt to have it here and then here dot JSON so we can set the user the access token we grabbed it from result access token so this will set it in either case because either we got an empty access token or we got the access token so it will set it to an empty string or we set it to the actual access token that we got then we can set the loading to false right and just below here we cool this check refresh token and we have to do it like this because you can't have an async use effect so you just create an async function inside of the use effect and call it like this and this means that it will just fire off this when we mount the application so this will just run one time and we can actually before we return or JSX we can actually check if loading then we just turn the div we return a div that says loading so we save this one I can try it out as you can see here now as I reload the page you can see that it loading flashes here so it grabs the new access token from a refresh token endpoint so that's good we don't have to login as long as we have a valid refresh token so that's how a refresh token work as long as it's valid you can just call that endpoint with the refresh token and it will send back a valid access token for you to use in your application so that's very convenient to have that one and don't need to login every time then we can create our logout function here as we're in this component now so we have this logout callback this one we can just await fetch and from our local host port 4000 we have this endpoint that's called logout and we set a method to post and we can also include the credentials like so then this will wipe out the cookie but we also want to reset our application on the front-end clear user from context set user and we just give it an empty object for this one and then we also want to navigate back to start page so new navigate and forward slash right we save it and we can see if it works will log out and you can see we go to the start page you can see that it redirect us to the login that means that we don't have a refresh token now because we logged out so we login again and it's showing us the content and that's great and if we reload it it will grab a new access token as long as we don't log out but if we log out it wipe out the Refresh token so we have to login again all right great it works you can also see here in the console log that the access token is just an empty string okay we can create the register component also and we can actually just copy all the code from the login component and paste it in the register component of course we're going to rename this to register and also export default register we have to change a few things here now we're not going to need a context for this one for the use effect just use stale so we can delete these ones here and delete the context we are going to use the email and the password local state this one we change this to register so we hit the register endpoint instead the method is going to be post credentials yeah we can try it we don't need to include the credentials here because we won't send along the cookie the headers can stay the same the body the same everything is the same here and we're not setting a user here so we can just remove this one and if result of error we can just console aughh we want to know this error so consular result message no this is actually if we don't have an error so we just can console log out the message we get back and then we want to navigate to the front page to the home page else then we come to logout the result of error alright we can remove the use affect the and this change is going to be the same and we can change this one to register instead everything else is going to be the same yeah and also this one here should say register and we save it we can see if it works so we go to the register and you can see it changes here it's the exact same otherwise but we just changed these ones here we can just try to register without the user as you can see we can now create this is a bug here actually we can create an empty user and that shouldn't be possible so we have to check that in our API also of course but not for this tutorial okay so we just created an empty user and we can see in our console if we go to our or API here you can see that we created this one we don't empty email and this password that gets generated is from an empty string and that's no good of course but if we try to create a user that's the same as already in the database it should warn us yeah user already exists and it doesn't matter if we write another password here or something but we can create maybe put a two there and we register and you can see the user is created and we console.log it out here so we can see that it gets traded and it's put in the database that's not a database that's or fake database maybe you should get login automatically when you create a user and we're actually logged in as a not user now because yeah this is not a production app and I just want to show you how this stuff works now so yeah we just created the user but we logged in as another user and that's no good of course but it works we can register user and we can login and we can logout so if we login with the new user we created you can see first yeah it's just that the password is not correct and I had a same password we can login with user instead so that's great okay it's working so this is how the flow is when you send tokens to your client until your API and yeah it's very convenient that you don't have to login all the time and you can just have these tokens that will simplify everything for you that will simplify everything for your juicer it's not simple to do this stuff actually ok so we have one more thing to do we have to create a protected road to show you how you can protect data and use your token to get that data yeah and I just realized why our CSS isn't working as it should and that's because if we move inside of the apt of J's file the class name is a capital A here and app just change that one to a lowercase a and save it and it should work yeah it's a little bit nice to know you can see looks more like a regular login form now and yeah it's centered and the nice stuff like that so yeah that's great move back inside of the protected KS file for this one we are going to need the use affect the youth stayed and use context we're also going to import the user context from dot dot forward slash app and we can remove this one and create curly braces so we have the Const user and we use context and send in our user context then recreate a local state content and set content you stayed and we give it initial string of you need to login and of course there's many ways of doing this so this is just one way to show you a simple solution how we can get the protected data and show it in our component then we're going to have a use effect and this one is going to fire off when the user changes so we create an async function that's called fetch protected we have yet again the const or result we await and we await again the fetch and from our local host forward slash protected we are going to grab our data we have a method of post the headers are going to be content - type application forward slash JSON then we have authorization this is really important here we send along this property here that's called authorization we give it a string we have backticks here now with a beer and then we give it the user access token and it will back T so this is the standard of sending your access token you have this beer in front of the access token so that's what we stripped away in our API when we get to access token and we actually can look at it here up here you see we get the token by splitting authorization and we get an array with the values and the value at the index one is going to be our access token so we removed this way were the bearer beer-beer yeah I really don't know how you pronounce that yeah so yeah it may be wrong but I hope you understand what I mean so that's how we stand along the access token and down below here we just convert it to Jason and then if result data if we get some data back we set the content with result of data and here we have to call or fetch protected down below here we just returned a div with the content so obviously this is not going to change if you don't get any data we just displaying you need to login otherwise we display the data we get back so we can save this one now and see if it works now you see we could look in now with not a user or a password because we created a completely empty user and you shouldn't be able to do that but we login now and we can see if the protected words no it doesn't work actually so we have to figure out why yeah and I'd done it again I can see here now there should be an S near I missed that again I think that's the third or fourth time in this tutorial as it's really easy to do something like this especially when you see there and record everything and are going to show you this stuff so yeah make sure you have an S on the headers so I try to log in and I go the protected roads and it says this is protected data so that's good that's fine it was just that little s that messed everything up here that's the beauty of coding one little small typo can ruin everything for you so as you can see we're getting the protected data cause we send along the access token here so that's how you protect data with your API and you need a user to send along the access token to get the data so this is it actually maybe it seems a little bit much and yeah it is authorization and authentication is really advanced stuff so it should be a lot I think I actually find it a bit hard to explain also because it's a very advanced topic and I hope you learned something from it I will appreciate if you want to subscribe to my youtube channel and you can also add me at twitter at Valen fart I also got a few premium courses in react out there there on my own platform WWE Beam fark.com and I have a few on udemy also no but I'm going to move them to my own platform in the future so hope you enjoyed it sealing another one
Info
Channel: freeCodeCamp.org
Views: 66,885
Rating: 4.9427752 out of 5
Keywords: jwt, json web token, jwt tutorial, what is jwt, what is json web token, how does jwt work, jwt authentication, jwt auth, jwt authorization, json web token explained, jwt token, jwt explained, jwt in depth, learn jwt, jwt security, jwt decode, jwt encode, jwt vs session, json web token authentication, json web token tutorial, json web token in depth, using jwt for authentication, how to use jwt, why jwt, why use jwt, jwt node js
Id: x5gLL8-M9Fo
Channel Id: undefined
Length: 100min 59sec (6059 seconds)
Published: Tue Nov 12 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.