Placeholder Image

Subtitles section Play video

  • it is finally here this video we're going to be talking about J W T authentication using know Js and express.

  • And we're gonna be recognises into two separate parts in the first part.

  • We're just going to do a simple J W T authentication will recreate tokens, sent tokens to users and authenticate those tokens on our server.

  • And in the second part, we're gonna talk about how we can use a refresh token in orderto automatically refresh our JWT tokens to increase the security of our server, and also revoked privileges from users that we no longer want to access our server similar to how a log out function works.

  • So make sure you stick around to the end of the video.

  • So you get both parts of this video.

  • So with that, out of the way, let's get started.

  • Welcome back to Webb.

  • Have simplified my name's Kyle.

  • And my goal is to simplify the web for you so you can start building your dream project sooner.

  • So that sounds interesting.

  • Make sure subscribe to the channel for more videos just like this one.

  • And for this video, as always, I have visual studio code opened up completely blank folder so we can start this project.

  • And the very first thing we need to do is initialized this project with NPM.

  • So if we just type NPM, innit?

  • Dash, why is going to initialize our project with all the default settings?

  • And now we can install the libraries that we're going to be using the library's we're gonna be using.

  • As I mentioned in the intro, we're gonna be using express Soviet type NPM.

  • I express.

  • We also gonna be using a library called Jason Webb Token All one word.

  • And then lastly, we're going to install dot e N V, and this is just going to allow us to use a dotty envy file, which is going to contain our secret tokens for J W T.

  • So we can just create that now dot envy.

  • And this is where we're gonna put those secret tokens.

  • Lastly, we're gonna install a development dependency and PM I dash, dash save Dev, and this is called no demon.

  • And what node Mom lets us do is automatically refresh our server every time we makes changes to it.

  • So we don't have to manually close and restart our server ourselves And as soon as that finishes downloading, we're gonna create a script which is going to allow us to start our server using node money really easily.

  • And we're gonna do that on a file called server dot Jason, this is going to be our main server file.

  • So now, insider package Da Jason, you can see all of our dependencies air showing up in here, and we can just come down here and type in Dev's start.

  • And we want this command to be node Mon, and it's going to run our server dot Jason file.

  • So this is going to run our service, Jason using Nordmann.

  • And we can start that by just running NPM Run Dev start.

  • And it's going to run that file for us.

  • And of course, we're going to an air because I forgot to save my package Dodge a son.

  • Now let's run that again.

  • And as you can see, it started up our server and since we have nothing in it, it just exited out.

  • Which is fine now is we make changes.

  • For example, if we put a concert out log, put Hyeon here, save it, you can see that it's actually refreshing our server every time.

  • So to get started with our server, we want to first important express.

  • Will you just do that by requiring the express library And in order to set up an express server, we need to get the at variable, which is going to come from express so we could just call the express function and then say ap dot listen and tell what we want to listen.

  • For example, on Port 3000 now we have an application running on Port 3000.

  • But of course it doesn't do anything yet.

  • In order to get our application up and running, let's actually just create a simple route an app dot get route.

  • This is going to get all of the post inside of her application.

  • And this is of course, going to have a request and a response.

  • Variable hopes response.

  • And inside of here we could just run a function.

  • And inside of this function, all we want to redo is return a list of post socialist creative variable, which is going to have all of our post inside of it just like this.

  • And this is going to be an array with objects.

  • We're gonna have a user name for the person that created the Post.

  • So, for example, me and we're gonna have a title for that.

  • And we can just say Post one and let's just put to post in here for now.

  • So if I just copy this down and we're gonna change this user name here to be Jim never go.

  • And, of course, the title should be post two and inside of our app Target.

  • We could just return that.

  • So we can say resident Jason and we want to return our post.

  • Now, if we say that, create a new file called request dot rest.

  • What's not rest, not recess.

  • Let me change that real quick.

  • There we go.

  • And this is going to allow us to make arrest.

  • Request a P.

  • I request to our A.

  • P I.

  • You can use something else like postman, but because I have the extension installed in visual studio code called the rest client down here.

  • It allows me to just use a dot rest file to make these calls.

  • And this dot rest file is really simple.

  • We could just say we want to make a get request to http local host Port 3000 and we just want slash post.

  • So now if we send that request, you can see we get the list of our post back for us.

  • So we know that our application is working and running properly.

  • Now, the next thing for us to do is to actually authenticate our request using J W T.

  • So we don't let everyone access the post and only specific users, so we could just create a route to do that.

  • We can say ap dot Get this is going to be our log in route and, of course, is going to take a request and a response.

  • And the very first thing you do in this log in route is you want to authenticate the user.

  • And in our case, I've already done a video on user authentication using passwords and usernames.

  • So if you want to check that out, it's going to be in the cards and the description below.

  • So what is gonna ignore this portion of the authentication so we can focus purely on how J.

  • W T works in the authentication process?

  • So the next thing we need to do is actually create that Jason Webb token.

  • And to do that, we want to require that library we used earlier.

  • So we can say const.

  • And we want just j W t.

  • Which is equal to require of Jason Webb Token.

  • Also, since we're going to be passing Jason to this app dot Get, we need to make sure our server can handle that so we can say ap dot use and we want to pass an express about Jason.

  • This just lets our application actually use Jason from the body that gets passed up to it inside of request.

  • And we're gonna change this to be a post actually instead of agate, since we actually want to create a token.

  • So post makes more sense than get now inside of here.

  • We want to get the user name so we can say constant use.

  • Your name is equal to request that body dot user name, and now normally you would make sure you authenticate the user first.

  • But as I mentioned, that's going to be in a separate video which I've already done and you can check out now that we know this user has access to our application and has passed the correct user name and password.

  • We want to authenticate and serialize this user with Jason Webb tokens.

  • Now, if you're not already familiar with Jason Webb tokens and how they work, I have an entire video talking about why you should use Jason Webb tokens and how they work.

  • So you can check that out again, linked in the cards and the description below for this purpose of the video, we're just gonna worry about the implementation of Jason Webb tokens, and it's really actually quite easy to create a Jason Webb token.

  • We just use that J W T library and we pass it DOT sign, and the sign is first going to take our payload, which is essentially what we want to serialize, and we want to serialize a user object.

  • So let's just create a user, and this user is going to be equal to hear just an object which has name, and we want to pass that as our user name.

  • And now we can say that we want to serialize our user and in order to serialize them, we need some kind of secret key.

  • This is going to be the next parameter and we're gonna get this from our environment Variables.

  • So process dot e n v dot access lifts access token secret.

  • Just like that.

  • And we can create this inner Dottie envy.

  • We can say access token secret, and we need to set this to some form of secret value and a really easy way to create a secret value.

  • Is using the crypt library inside of know Js.

  • So what we can do is just open up another terminal and if we just run note here, we can just run any no jazz code.

  • We want to quit choir, the Crypto library, and all we want to do is we want to get some random bytes so we can say random fights.

  • Let's just say that we want to get 64 of them, and then we want to convert this to a string which is going to be in hex, a decimal.

  • Now we enter.

  • This is just going to give a random list of characters If we run it again, you see, we get a completely different random list of characters.

  • We can just copy this up as our access token secret.

  • And since we're going to be doing refresh tokens later in this video.

  • What set up our secret for a refresh token as well would issues this other value so that these have two different secrets.

  • That's really all that you need to make sure is that the secrets for both of these are completely different.

  • Now we can save that and go back into R J W T sign.

  • And right now this is complete.

  • We could add an expiration date to our token.

  • But since we don't have any way to refresh our token jet, we don't want to add any form of expiration date.

  • So we can just say that this is going to be our access token.

  • And what we want to do is just return that so we can save.

  • Red's got Jason and we want to pass down our access token as our Jason.

  • So now when we make a request to log in whatever user name, we pass up assuming it's authenticated correctly, it's going to create an access token for us.

  • And then Access Token is goingto have the user information saved inside of it.

  • That's what we're doing with our sign here.

  • So let's go over and actually test this.

  • If we just put in here three hashtags like that, anything that comes after it is going to be a different request.

  • So we could just say Post, we want a post to this http local host 3000.

  • And this time we want to do a log in.

  • And we want our content type here to be Jason.

  • So we can just say application slash Jason and then in our body, we need to pass up that user name.

  • So it's type in user name.

  • And let's just say we want to do Kyle for example.

  • Now, if we send that request, you can see we're getting air secret.

  • Private key must have a value.

  • And this is because we're never actually loading our Dottie envy variables into our process dot envy variable here.

  • And we can actually do that really easily.

  • Just at the very top for application.

  • We just want to put require, and we want to put dottie envy dot config.

  • Now, if we say that and make a request, this should work.

  • And there you go.

  • You can see we have an access token being returned to us that has no expiration date that has the user information saved in it.

  • So we can access any of our end points with this user information here.

  • So now, in order to test that, what's actually creates the middle, where which we're going to put on our post here, which is going to authenticate our token so we can say a function here.

  • We're gonna call it authenticate, authenticate, token.

  • And of course, since it's a middle where it's going to take request response and next and then inside of this function, all we need to do is we want to get the token that they send us.

  • We want to verify that this is the correct user and then we want to return that user up into the function here.

  • Forget post so we can call that authenticate token function as our middle where so we know we have that in our post and now inside of this function, we need to get the token, and this token is going to come from the header and we're gonna have a header called Bear.

  • So it's gonna say bearer, and then it's going to have our token afterwards.

  • So this string over here our token is going to come after the keyword bear and that's going to be in our authorization header.

  • So in order to get this header, we could just say cost off.

  • Header is going to be equal to request.

  • We want to get the headers and then from that headers, we actually want to get the authorization header which is going to have the format of bear followed by our token.

  • So then all we want to do is get our token portion.

  • So what we need to do is say that our token is going to be equal to off header flips off header just like that and we want to get this split.

  • So we're gonna split it here on a space because as you know, there's a space between bear and token and we want to get the second parameter in that array.

  • So we just say, 01 over here and this is going to be this token portion of our bare token and in order to make sure that we actually have a header, we first need to do off header and and essentially, what this is saying is if we have an off header, Then return the off header token portion which we split on the space otherwise just return undefined.

  • So our token is either gonna be undefined or it's going to be the actual token.

  • So we could do a check to make sure to see if our token is no.

  • So if our token is no, we just want to return to the user and air code, saying that they don't have access, so we can say send status and we want to send a 41 status code so that we know that they have not sent a token tow us.

  • Now if we get to the portion after this token check, we know that we have a valid token.

  • So we need to verify that token.

  • We could do that with J W T.

  • Verify that we want to pass it the token as well as the secret that we actually hashed that token with.

  • So we can just say process dot n v dot access token secret and this is going to take a call back, which has an error, and it's going to have the value we serialized, which in our case, is this user object so it's gonna have our user as wolves and air.

  • And the first thing we want to do, of course, is check if we have an error.

  • And if we do, we want to return another status code to the user saying they don't have access.

  • So we're gonna send a status.

  • This is gonna be a 403 which essentially says that we see that you have a token.

  • But this token is no longer valid, So you do not have access.

  • Now, if we get past this, we know that we have a valid token so we can set our user on our request.

  • We consider request that user is going to be equal to this user object.

  • So we know we have a user and we could just call next just like that so that we can actually move on from our middle Where now, if we save that, make sure that this is next instead of next tax.

  • Don't misspell that up here.

  • We now have access to our user.

  • We can say request that user to get our user so it's actually filter the list of post.

  • We can say dot filter and we want this, of course, to be a post, and all we want to do is get the post where the user name is equal to request that user that name.

  • So this is only going to return the post that the user's access to.

  • So if we log in as Kyle will get post one, if we look in his gym, will get post to, and if we log in as anyone else, we won't get any posted all.

  • So let's test that.

  • All we need to do is send a request to log in.

  • We're gonna get an access token.

  • Let's just copy that and up here instead of our post.

  • We want to send along the authorization header, and as you remember, it goes bare.

  • And then we pay start token after that.

  • Now, if we say that and request our post, you see, we're only getting the post for Kyle because we've logged in his Kyle.

  • Let's log in his gym, send that request copy over Jim's access token and paste this in here, and we should get back just Jim's post.

  • So now we know that our authorization and authentication using J sound Web tokens is working properly.

  • It's saving our user, and everything's great in orderto further emphasize the power of Jason Webb tokens and how you can use them across many different servers.

  • Let's just go into our package dot Jason and create a dev start script to here, and we want to start up server to dot Jason, which were just gonna copy this server dot Jason, rename this to server to dot Js And all we're gonna do down here is change our listen to be on Port 4000.

  • So now let's start that up.

  • We can just say and PM Run, Deb, start to hit.

  • Enter.

  • And now we have two different servers.

  • Let's make sure I save my package.

  • Jason, rerun that.

  • And now we're have two different servers run on port 3000 and one on Port 4000.

  • And the key thing is, they both share the same access token secret.

  • So what we can do is inside of request.

  • We can actually log in on our port 3000 as you can see here, are logged in.

  • Worked directly.

  • Copy.

  • Over this token, we can use this on our other server at Port 4000 and If we send a request, it still works.

  • This is something that you can't do very well when you use session based authentication because your session is saved on that particular server.

  • But with J.

  • W t.

  • All the information in the token, so we can actually use it across multiple different servers.

  • So what we're gonna do next is implement refresh tokens which allow us to actually take our authentication server and move it outside of our other third server.

  • So we can have one server which handles all over creation of tokens, delusion of tokens and refreshing of tokens.

  • And another server which handles on Lee are specific use case of getting post saving post all of our different AP I related tasks, but not authentication.

  • So in order to do that, let's rename server to hear toe off server.

  • So we know that this server off server is only gonna be for authentication, and our normal server is going to be for everything.

  • That's not authentication.

  • So what we can do immediately is remove our log in section from the server.

  • And there we go now are normal server.

  • All it has is the get for post and we can authenticate our token, but it has nothing else inside of it.

  • We can just save that and our package die.

  • Jason, here, we want to change our death.

  • Start to be deaf.

  • Start off.

  • So where you have a normal day to start, and then our off one, which is going to be starting our off server dot Js.

  • And of course, let's just cancel out of this and make sure we run our dead start off, and now it should start up our off server and our other server is already running on a different port.

  • So we have our server running port 3000 and our office server is running on Port 4000 here and on or off server.

  • We can actually remove all this post related code because we're no longer gonna be allowing post on this server.

  • It's only gonna be log in, log out and refresh tokens.

  • So before we start building and implementing our refresh tokens, I need to talk a little bit about why we need a refresh token right now.

  • When we create a token, it has no expiration date, which means anyone with access to that token will have forever access to that users account, and they could just constantly make request as if they were that user.

  • As long as they have that access token, it's very difficult to secure that because they just have infinite forever.

  • Access would be like giving up your a p i ke when you're accessing a P I.

  • The user just now has access forever.

  • The idea of a refresh token is that you save the refresh token in a safe spot, and then your normal access tokens here have a very short expiration date, so that if someone gets access to your access token, they only have access to your account for maybe a few minutes before the axis is revoked.

  • And then the user must use the refresh token to get a new token.

  • And now this does have the same problems where your token could get stolen and someone else could use that token to refresh your token.

  • But that's where the idea of invalidating a refresh token is.

  • You can essentially create a log out route, which deletes a refresh token so that the user now can no longer use that refresh token.

  • Essentially, it removes it from the list of valid refresh tokens.

  • So really, the main reason to use a refresh token and so that you can invalidate users that steel access that shouldn't have access.

  • And the second reason is so that you can take all your authentication and authorization code and move it away from your normal server.

  • As you can see, we have two different servers and one is specifically for authorization.

  • So you can scale these servers separately.

  • If you have a lot of authorization, you can make your authorization server bigger without having to make your other servers bigger as well.

  • It's really great for when you want to do with micro architectures or things like that.

  • So the first thing we need to do is let's just create a function which creates an axis token for us, and we also don't need this function for authenticating.

  • So let's just create over top of this a function which is going to generate access token, and we're gonna pass it.

  • The user we're gonna generate this token for, and this code is gonna be very similar to this code right here.

  • What's copy this down.

  • We're gonna make sure we return this, and the only extra thing we need to do is add in an expiration date, so we could just say expires in.

  • And for our use case, we can put anything, For example, 10 minutes.

  • Usually you're gonna have some short minute range, maybe 10 15 minutes.

  • We're gonna just set this to 15 seconds just so I can easily show you how the tokens expire and how you can refresh them.

  • But again, you would want to make this much longer in a real application, something like 10 15 minutes, maybe 30 minutes.

  • Whatever works well for your use case, now that we have that done was just changed This code appear to call that function to generate our access token.

  • And now everything's working.

  • Fine.

  • But our tokens going to expire in 15 seconds.

  • So we need to create a refreshed Okay, let's just do that right here.

  • We can create a refresh token.

  • This is just going to be equal to J w t dot sign.

  • And we want to sign a user.

  • We essentially want to put the same user inside a ball tokens so we can easily create a new token from our refresh token, which uses the same user.

  • We also want to get the environment variables.

  • And we want to get our refresh tokens secret so that we can serialize this on.

  • We don't want to put an expiration date on a refresh token.

  • We're gonna manually handle the expiration of these refresh tokens.

  • And we don't want J w t to do that for us.

  • Now, the last thing to do is to return this refresh token toe our user just like that.

  • And now, if we go over to our request and we make a post on local host, this is going to be 4000 toe log in.

  • If we send that request, you can see we now getting access token and a refresh token back.

  • And let's make sure we change this back to 3000 for post.

  • And if we try to make a request, this is most likely gonna fail, since I don't think I got a quick enough.

  • Okay, I did.

  • So it hasn't expired yet, but if we keep sending a request, you can see after 15 seconds, we're now forbidden from accessing this route, and we need to use a refresh token to create a new one.

  • So now let's go over to our off server and we need to create a new function.

  • There's gonna be apt Outpost and we want to post token.

  • So essentially, this is going to be for creating a new token.

  • It's gonna be a request and a response.

  • And inside here, we're gonna take in a refresh token so we can get a refresh token.

  • It's gonna be equal to request stop body dot token.

  • And this request is going to look just like this.

  • Looks like just create a really sample request we're gonna post to http slash slash local host 4000.

  • We want a post to token, and we're going to, of course, make sure our content type is going to be set to Jason and inside of our Jason.

  • We're gonna pass a token, and that token is going to be our refresh token.

  • Right now we don't have one.

  • But if we were to make a request here, for example, here's a refresh token we can use, and we could pace that in there, and this would pass up that refresh token to our off server here and we need to use that refresh token and check to see if we already have a refresh token that exist for that.

  • So normally you'd want to store your refresh tokens in some form of database or some form of red is cash.

  • But for our use case, we're just gonna store them locally in a variable.

  • We're gonna call this refresh tokens, and we're gonna set this to an empty ray.

  • Gonna initialize this with let just like that.

  • And now this is not a good idea to do a production, because every time your server restarts, this is going to be emptied out.

  • But it's a lot easier to show you and demonstrate with than creating an entire database just to store these tokens.

  • And the first thing we need to do is every time we create a token, just like down here, we just want to set our refresh tokens dot push.

  • We want to push in that new refresh token we just created.

  • So now we have a record of that refresh token, and all we can do inside of this token is check if that token actually exist.

  • So first we want to say if refresh token is equal to know.

  • We want to return our status down here so we can say residents.

  • And what does that send status?

  • Me Just close under the section over here.

  • This is gonna be a 401 status.

  • Now, the next thing we can do this, my spell things correctly is we can check if our current refresh tokens includes that refresh token that we got sent to us.

  • So what this is saying is do we have a valid refresh token that exist for this free?

  • Fresh?

  • Essentially.

  • Does this refresh token still valid?

  • Have we removed it, or is it still good?

  • And if it does not exist, what we want to do is again return saying that they do not have access.

  • So we're gonna send a status this time saying 403 Now, if they get all the way past all those checks, we can actually verify this refresh token.

  • So we can just say refresh, token.

  • We want to get that secret variable.

  • So process dot n v dot refresh token, secret.

  • And of course, we're gonna have an air as well as our user object being returned inside of this callback function.

  • And of course, we want to check our error first.

  • And if we have an error, we could just return that air so we can save return.

  • And we want to send down a status of four or three very similar to our normal authentication.

  • But now we can do is actually create our access talking.

  • We can say constant axes.

  • Token is going to be equal to generate access token.

  • And you would think we could just pass this user object.

  • This user object actually contains additional information such as the issued at date of our token.

  • So we actually need to get just the name so we can say we want to get the name and the user dot name that we were passing down just this raw user object and not all that other additional information.

  • Now we can return that information by just sending resident Jason of her access token just like that and that we're finally ready to test this.

  • So if we go over here and we log in gym, you can see we get both a refresh token and an access token.

  • If we copy our refresh token pasted into our token function on de copier access token and paste it up.

  • Here we can send some requests and you can see it's working.

  • It's working, but eventually we're gonna get the forbidden status.

  • We no longer have access.

  • So let's create a brand new access token.

  • We concocted that access token pasted up here and that we have access again for another 15 seconds and eventually we're gonna lose access.

  • When you even notice that these were on different servers, this is Port 3000 and these run for 4000.

  • So our authentication, where we log in and create refresh tokens and handle refreshing our tokens all happens on a different server that are actual AP, I which is great.

  • Now the next thing I want to talk about is how to actually d authenticate refresh tokens because right now, forever and ever and ever, user, just click this send request button, create infinite access tokens for user's no matter what, and as long as they have that refresh token, they can do that.

  • So, in order to prevent this, we need to have some form of delete function.

  • We're just gonna call this a delete here and we want to do, For example, log out what this is going to allow us to do is actually delete those refresh tokens.

  • And this is really easy.

  • Normally you have didn't leave them from some database.

  • But since we just are storing them in a variable here called refresh tokens, we could just say we want to set our refresh tokens equal to a filtered version of our refresh tokens.

  • Where all we're doing is we're just checking me.

  • Just close out of this here.

  • Where is checking to make sure the token that is inside a refreshed tokens is not equal to our request That body dot token that we passed up to it and then all we want to do is just send a status we're gonna send to Oh for saying that we successfully deleted this token.

  • Let's say that and actually make a request for that so we can just say delete and we want to go to local hopes.

  • Local host 4000.

  • We want this to be log out.

  • We want our content type to be Jason, of course, And inside of here, we need to pass that token.

  • So let's actually do another generation here where we're going to log in our user, you can see we get access token and we get a refresh took in.

  • Let's copy this refresh took in over into this section, and we also want to copy it into this section for deleting so we can actually refresh this token.

  • As you can see, we're getting new access tokens and everything's working.

  • But if we click to delete, you see we get to a four means they successfully executed, and now we try to actually create a new refresh token.

  • Her access token.

  • You can see it no longer works, and that's because we removed it from this list.

  • So the user and no longer has access to it when they try to create a new token and exits out right here when it's checking to make sure that refresh token already exists.

  • And that's all there is to implementing JWT authentication in know Js and express.

  • If you enjoy this video, make sure to check out my other videos linked over here and subscribe to the channel for more videos just like this one.

it is finally here this video we're going to be talking about J W T authentication using know Js and express.

Subtitles and vocabulary

Click the word to look it up Click the word to find further inforamtion about it