.NET 6 Web API Create Refresh Tokens - JSON Web Tokens (JWT)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello friends thank you for watching this video i am muhammad and today we are going to be discussing a very interesting and very exciting topic refresh tokens and basically refresh tokens are a way where we can actually keep the user authenticated into the application without actually having the need to the need to relog in again so basically whenever we generate a jwd token a refresh token is generated with it which is basically a secondary token to the jwt token and this token will allow us to reauthenticate the user without actually having the need for them to relog in so whenever we're generating a jwt token which is a short-lived token agita with a refresh token which is generated which is a long-lived token is also generated with it we're going to go through the logical part first where we're going to be discussing the theory of it and basically where do we need to implement it and then once we have discussed the theory we're going to delve into the code itself and actually try to build the functionality from a to z and basically try to test it and make sure that everything is working as it should be so this should be a very exciting video if you like this video please like share and subscribe it will really help the channel now let's grab our cup of coffee and let's jump into it before we open rider i'm just gonna tell you where you can find the repository so if you go to my github so it's gonna be github.com forward slash muhammadlawn87 if you're not following me there please follow me so basically once you go there you go to repositories so inside the repositories you're gonna find dot nut six dash email verification so that's the one that we want so all you need to do is just click on this repository and basically clone it down to your local machine i have already done that so basically once you go and get the repository on the source code again please follow me if you're not following me there uh what we can do what we want to do is basically i want to open it in ryder or you can open it inside visual studio or any of the applications that you want to use and basically once we do that uh what we're going to be doing is we're going to be mapping the team's controller so let's run it and basically and let's see uh what to expect so let me run this and us not run and now the application will run [Applause] and we can see it's running on port uh seven seven thousand one hundred and ninety two so let's go to our web browser and let's open swagger [Applause] okay so inside our swagger we have basically our teams controller and inside our team's controller what will what we have is different endpoints so we have the get post batch delete and gut to make it easier for us we're going to try to explain this based on gut so basically the gut functionality here uh if we click on execute i think do we need to pass yeah we need to pass the [Music] [Applause] we need to pass the authorization token so we're getting unauthorized um i don't remember the password to logging in but what we can do is to make it a bit easier for ourselves just for now then we're gonna remove this so let's just remove the required authorization and then let's run our application again so we can see what are we actually expecting so right now if i just click on execute again i'm getting the information saved okay perfect so now what we're going to be doing is to get this api teams request we're going to add the source code implementation or basically what we're going to be is basically we're going to add the illustration of how this this should work so here we're just going to say request i'm going to say get themes so it will be clearer perfect so we don't really need this so let's delete this let's clean up let's clean everything here so the easiest way is to just choose and delete delete don't need any of this because we're gonna basically create everything uh from the beginning so let's delete this let's see this this all of these we can delete okay perfect so now this is the start of our request we want basically to get all of the themes as simple as that so first of all let's take this box here we put it here and we're going to say here send request so before we send the request we need to prepare requests because this is very important we need to prepare the request so you might think to yourself okay what's preparing my request basically i need to add the required headers for them so to add the headers we're going to say here add the security headers so we'll add it here let's make it like this we'll add security header which is basically we're attaching the jwt token to the request i'm going to put jwt token and basically once we attach the security header to the request we're going to be sending it so once we send it it's going to be basically received by our back end so what's the back end going to do so the first thing that the back end is going to do is check the uh time for the token because the jwt tokens are short-lived token and basically every jwt token that we generate have a certain amount of time to live so for example it could be 5 seconds it could be 10 seconds 15 seconds they have very short amount of time to live and basically we need every time to when we send the request we need to make sure that the token that we are sending is uh within that time to live that they have so for example if we generate a token and it has five seconds we need to send the request with that token within that five seconds if we send it after that five seconds it will not work the server say okay this token has expired i cannot use it i need a new token so that's why we need to check the time for the token to make sure that it's a valid token so check time uh time to live let's say it's called time to live time to live for the token and then basically actually this needs to be a decision so let's make it as a decision let's attach this to this decision i don't know what this is doing okay let's make it like this okay and basically here we need to check the time to live let's make this a bit bigger okay that should be fine so we're checking now the time to live and basically let's see okay and basically what we need to do let's make this a bit smaller approaches just my ocd okay so we're gonna stray see if we can make it yeah better like this so we're checking the time to live for the token so if it is valid we're gonna be continuing this we're gonna be continuing it processing the request so we're going to say here valid token actually we need to do stuff more before that before we can actually process the request so let's delete this so it's gonna be valid time not token because that's the first thing if not actually you just make it like this so this is going to be the second thing and so first of all we're going to say if it's not invited so we say expired token so in case it's an expired token what do we need to do we need to send back the results from the user telling them that invalid token and we need to stop it as simple as that oops so let's take this down and we need to connect this one to this one okay great so now that our uh in case the token is expired we're just basically telling the token is expired and it's an infrared and we're stopping the request so in case it's a valid token so that's the second thing basically we have checked that the time is valid so we can process the next check that we need to do and here we need to check who generated this token so based on that if because if you remember when we are doing the jwt token and generating it we have a secret key and we have certain types of algorithm that we are utilizing in order for us to generate this token so we need to make sure that whatever token signature we have it needs to match to our code in order for us to make sure that this token belong to us so if it is uh if it doesn't belong to us or basically we figure out that it's not what we want so or basically it's trying to mimic a token that we have so we need to send we're just going to say here invalid signature because it's invalid signature we need to stop the request and basically stop it right there and then in case so let's make this let's connect this one to this one easier like that okay but in case it actually uh has a valid signature now we can actually process there's a lot more checks that happens but these are the main two that we want to cover right now so in case everything goes to plan basically the request is basically allowed to go to the controller itself and basically it's allowed for us to process that request because before that we were not allowed to even like process that request so how does it work when the request reached our application before it reached the controller itself it has to go through the security middleware so we have the application we have the application itself receiving the request and then once it received the request it goes to the security middleware it makes sure all of these uh all of these verifications are done if they are passed it goes to the controller if they are not passed it has to go back with an invalid request invited token or some kind of an error so here because we said it's a valid signature and here we can say valid time by the token so we just make sure that we are obeying it and then basically once it goes to the actual controller it goes to the database fetch the data and then once it's fetched the data what are we gonna be doing we're just gonna prepare the response and then once we prepare the response we're just gonna send it back let's take this as an example and we're just gonna say as simple as okay great instead of granted we can return return response okay so this is what happened let's do a quick overview so basically we prepare the request we before we send that we attach the security header with the jwt token we send it to the back and the back end is going to receive it it's going to check if it's available it lives within the valid time if it does live within the valid time uh it's gonna continue if not we're gonna send an invalid token back so in in case it lives within the valid time we're gonna check what generated this talk and all of this is done automatically for us but we need to just so we understand what's going on we are illustrating it here so in case uh that we have invalid signature we're gonna send invalid token in case it is uh on top of so many other checks we're passing the request to the controller once it reaches the controller basically it touch the data from the database prepare the response and sending it back to the front end as simple as that this is the flow of every single jwt token happen but what will happen in case our token expires before it actually reaches us so that's something that we need to take into consideration so just come to think about it i think this should happen before this one so let's just put this here just for a second let's okay let's take this one let's put it here and i think the first thing it checks if it's a valid signature and then uh we check if it's a expired token or not so we can say here invalid signature and then here just try token okay okay so the first thing that we check uh we are checking here is in essence as we said the signature if it's a valid or not uh who generated this token if it's a valid signature we are continuing if not we are making it stop so what happened here is what we need to do is instead of uh having the user here to do these calls manually so what do i mean by that so every time the user log in basically they got a jwt token and once they go again and they get a jwt token they are able to use that token with all of the subsequent requests that we have which is exactly what we want but we don't want every time that the token expires force the user to log in back again and basically get a new token it's going to be very cumbersome for the user so imagine like uh if you're you if you're utilizing for example instagram on our mobile phones and because instagram is authenticate uh based on jwt tokens for example with the server every every for example minute after as soon as the token expires is telling us please log in again to continue using instagram you can see how annoying that will be so we need a way so we can actually refresh those tokens and basically keep our system secure and keep our servers uh protected and our users information protected without actually compromising it and have a very good uh have a very good user experience as well and basically let us let the system handle all of the refreshing of the token automatically and having always a secure token automatically without us having to worry about it so how can we actually accomplish that and in order for us to do that what we can utilize and we can utilize something called refresh tokens so you might think to yourself what is a refresh token a refresh token is a way that we can actually request the new jwt tokens without actually having to log in again so it's a mechanism we can implement within our system or within the application that we are trying to build to get the new jwt token without actually having to actually log in again as we said previously so let's see how we can implement it so if we take this here let's copy all of this again because we're going to be building on that and let us just put it all the way down so here we're going to be basically implementing jwt token and you if you look at this and you think to yourself where do we need to implement it logically speaking we need to implement it whenever we are checking the time for this so we need to actually send back some information to the front and the front and needs to do some actions and then here we need to implement it so let's see how we can update this so it will reflect the refresh tokens so the first thing that we need to update is basically here actually it needs to go a stop before that the first thing that we need to do is whenever we are authenticating or with whatever whenever we are logging into the system uh either logging in when we get our jwt token what we need to do here is not only generating a token we need to generate a token and we need to generate also a refresh token so in essence whenever we are actually logging in a user instead of only generating for them a jwt token for them to utilize we need to generate two tokens we need to generate the jwt token and we need to regenerate a refresh token and that refresh token is directly linked to that jw token and if you don't know what the refresh token don't worry about it we're going to explain in details but for now think to yourself whenever we are trying to log in or whenever i use a login they need to have two tokens they need to have the login one the jwt one and they need to have their fresh one so that's the first thing the second thing is once they are sending any subsequent request they need only to send the jwt token unless we receive the response from the back end that it has expired so let's just update this so it will reflect the jwt token the refresh token so let's move these a bit further so let's just move them okay let's take this into consideration let's move that all the way here can you still see it yes you can still see it a bit but let me move it like that okay uh let's make this a bit longer so it will be easier how can i make this longer i'm not sure honestly but okay okay that's not now a bit longer let's take this again and make it a bit longer as well so let's move them here let's move this here and let's move this here okay so now let's do this like this because we don't want to change a valid token response we only want to do some changes here and let us fix this arrow i'm not sure if you can see it i didn't do anything yet i'm just like reorganizing this graph so it will look decent so what's going to happen here so if we send an expire if we check the time for a token after we receive it and it's a invalid token or basically it's an expired token what do we need to do we need to send here uh to the users instead of an invalid token we're going to say expire token so what's the front end gonna do so the front end basically is gonna prepare a new request and this is all happening in the background we don't have to do anything and basically it's gonna request new token and this can attach the refresh token and the jwt token so that's let me make this capital so the process is once we actually send to the uh to the front and listen front end your token has expired and we need to figure out a solution uh for you to get access so the front-end will be okay listen to me i'm able to figure this out i'm going to send you the refresh token the refresh token should be able to let you know that i'm an a real user and basically i have filed the credentials and you need to provide me with a jwt token so the front-end will prepare this request and it's going to send it back to the back end what's the back-end going to do so let's add this here so first thing the back end is going to do is check if the refresh token belong to the jwt token that's the first thing it's going to do it's going to check if this actual token that we have is actually a valid token forever for that uwt because every refresh token is completely unique to that jwt token so and because every jwt is unique to a user so now you can see why it's really important to make sure that it's a valid one so once i check it's uh actually this refresh talk and belong to this jwt tokens the next step for it is it's gonna check to which user it belongs to actually before it does that it checks if the refresh token did not expires because we know that refresh tokens are long lift tokens although they are long lived so they can live for like i don't know 30 days or like a few months but actually yeah they can live to that long but even if they live that long they can still expire so we need to check the expiry date so instead of making it like this let's make it as a decision and we can put this here and we can put check refresh token [Applause] expiry so in case a refresh token has expired there is nothing else we can do a user will need to log it back into the system so that's going to be the main request so in case a refresh token has been generated sorry has expired we cannot really do anything anymore we're just going to say it's been expired log n is required and the user will have to log in but in case the refresh token has not expired and basically the refresh token is still valid now we can do the work so the second step is it's going to be we're running out of space but don't worry we'll figure it out so the next step after we check that flash token is still valid what we need to do is we need to make sure that this token belonged to a user to check the token belong to the user so that's what we need to do and once we make sure that this token belong to a certain user then what we can do is let's move this a bit further because they're taking so much space and let's move them like this we'll figure it will reorganize it so it will look nice again don't worry but basically once we make sure that this user actually check if the token belongs to our user what is what what are we going to be doing we're going to go to the database check do the verification there validate the token once we've added the document in the database we're gonna get back a response so it could be let's copy this once we get the response back we're gonna generate a new token jwt token and a refresh token so once we generate both of them what we're going to be doing let's put this here once we generate both of them what we're going to be doing is we need to save them in the database so that's going to be one action so saving them save the new tokens and then what we can do is lastly is we return the response back to the user to the front end returns tokens response so that's what we're going to be doing after so this can happen simultaneously first we save and then after we save we're going to send the response back to the uh to the user to the front and excuse me and then once we send the response to the front and the front and again is gonna execute the same request that it executed all the way here which is preparing the request and then all of that it's going to go through that exam process again and basically let's make this a bit bigger even because it's just taking so much space see i'm not sure why this is acting like this let's see okay i'll fix this later it's fine let's just move these like this and let's move this like this and move this here and basically let's update this one here so basically this is gonna feed into this prepare the request and then once they receive it they're gonna attach the security token and then they're gonna send the request back which is going to be all actually what we can do something way more easier than rewriting or redoing the work basically this can be something like it goes all of the way here with the new token and sending it here so basically it's gonna restart that journey from the beginning as simple as that so let's put this back in i hate how flimsy this is but it's one of the free solution that we find and it's really good for all of that for free it's really good okay so let's put this here let's put this here and lastly let's put this here and let's close this circle here okay so let's explain what happened right now so i think it got a bit complicated but let's go through it one by one so we can explain what's going on so first of all i want to get my teams i'm preparing my request i attached the security token that i got when i logged in then i send it to the back end the back end is gonna check it does this talk and belong to me did i actually generate this token if it's yes if it's no we're going to send invited talk and we can't do anything we stop right there and then if it's a valid token check the time if the time is good we continue prepare the request and send it back we can see here we have a this long arrow coming here preparing the request and we're sending it back but in case the token is invalid or it's an expired token we're sending back to the front end like listen front end this is an expired token you need we cannot process your request so the front end will look okay if it's an expired token i know what i can do i can send you the refresh token so i can get a new jwt token so i can process my request so what's the front i'm gonna do is gonna basically send a new request to get a new jwt token and it's gonna attach the refresh token so once it's sent back to the back end the bank will be like okay i receive your refresh token on your jwt token i'm gonna check if the refresh token has not expired it's going to check if it's not expired it's going to check that refresh talk and belong to this jwt token if it does or is expired it's going to send an invalid token with nothing we can do the user will need to log in if it hasn't expired then it's going to basically check if it belongs to a certain user if it does it's going to validate the token against that user and then basically it's going to generate after all of those checks has passed it's going to generate a new jwt token with a new refresh token it's going to save it into the database and then it's going to return the response back to the front and under front and again you can start all the way again and process that request and do do that request so on so forth and all of that work which is happening is all happening in the background we're not we're not managing it we're not doing anything all of this is happening in the background and we're not doing any of it as a users but for the actual the actual code is automatically handling it and that's what we're going to be building so we're going to build it in a way where we're generating it we're able to directly authenticate with the new uh for the new request without actually having to reload and again and that's the goal of this refresh token makes our life easier from a user perspective and it makes our application much more secure so now that we have covered the theory it's time right now to jump into the actual code and see how we can implement jwt refresh tokens so if you haven't so already please make sure that you have the source code available on your machine so we can start if you're not sure where to find it again you can go to my github which is going to be github.com1087 i'll have all of these things available in the description down below and what you need to do is you need to get not six dash email verification repo and once basically you open it just make sure you clone it down on your machine and you can get started and once you have that you should be able to have the almost the same version that i currently have here so the first thing that we need to do is we need to go to our program.cs and inside our program.cs what we need to do is we need to update this here basically what we need to do is we need to actually try to abstract this a bit so we can make it a bit reusable and once we want to implement our refresh token it will be much more easier for us to do with right there and done so let's do it right now so first of all let's take this out of here and let's put it just here above this one so that's the first thing that we need to do and second what we need is let's create a new variable and we'll we'll call it token validation parameters equal and let's just take all of this here and let's paste it here and then we can take this new variable and assign it to this one instead of the other one that we used to have so that way we can actually utilize this token validation parameters and multiple places instead of just repeating it over and over again so now that we have done that the next step is we need to update our refresh tokens expiry time so as we said jwt tokens are short-lived tokens this means that they have a certain amount of time they need to live and i think the best way to put where the token will live out the amount of token the expiry time or their lifespan is in the settings so let's now go to our app settings and update it from there so inside my app settings where i have my jwt config all i'm gonna be doing here is i'm gonna be adding my expiry time and basically i'm just going to make it i'm just going to make it let's say one minute for now we can change it as many as we want but let's just make it one minute for now so once we have updated here the next step is we need to update this jwt model that we currently have so inside of models inside of do you think it where was it data let's see where we added this can't really remember so if i come here and i take a look at uh where is it jwt config let's see what it what does it live okay so it's inside the jwt configurations so here what i need to do is i need to add the same one here which is going to be of type so it's going to be prop span and then i'm gonna call it the same thing perfect so once i have done that and basically now uh i'm getting my expiry time for my token from my configuration now i need to go wherever i'm generating this token and basically i need to tell it that it needs to inject this variable dynamically from there so inside my authentication controller let me see where am i calling the generate jwt token method so here where do i call it here no i think it should be all the way at the end yeah generate jwt token and basically what i can do is i can get from here so instead of having this one like this i can just do underscore configuration dot get section and then i can just pass it and just put that value so it will be i need to convert it to my timestamp or time span of course but first let me just copy this paste it here and then let me take the name of the time frame i'll make it like this and then here what i need to do is i'm gonna put date time oh let's make this day time dot utc now dot add and basically i can add this here this time span let's see why is it complaining okay so we need to convert this to timestamp so what we need to do here is we need to put time spam dot parse and basically we can take all of this within the value as well and you can just put it inside all of this and once we have it here let's put it inside this i think this will work okay perfect so now that we have added our time stamp and basically we made this expiry time dynamic what we need to do right now is basically inside our auth results so inside our models here what we need to do is we need to add a new string which is going to be the refresh token so we're going to put string refresh token and basically right now whenever we are generating a refresh token uh with the token itself we need to return it to the user so they were able to utilize it so once we have done that the next step for us it's gonna be basically create a token request which basically allows us to store these tokens so let's get into it so the idea behind having this token request is whenever we are having a user who wants to actually refresh their tokens what do they need to send us they need to send us their jwt token and they need to send us the refresh token so we are able to provide them with the new jwd token because their original one has been expired so inside our dtos folder i'm going to create a new class and i'm going to call this token request and inside of this what i'm gonna be doing is i'm gonna put a prop and it's gonna be of string i'm just gonna put token as well i'm gonna put prop string and this is the jwt token that they need to provide us in order for them uh to get a new jwt token refresh token and let's add some validation so let's make these required so in case someone tries to send us a token without the refresh talking it will not work or they send a self flash token without the token it will also not work so now once we have done that the next step for us is we need to create some kind of a table inside our database where we are storing all of these tokens in order for us to match which fresh token belong to each user and basically based on that we are able to actually match both of them and do all of the logic that we need to do in order for us to make sure that this token that's coming in actually belong to this certain user so how can we do that it's very simple so inside our models table we're going to create a new class and we're going to call this class as simple as refresh tokens and basically what we're going to be doing here is we need to add all of the different fields that we're going to be adding that we're going to be utilizing in order for us to make sure that this token is valid so first of all let's make it as an integer as a primary key so we're just going to make it as an id and then we're going to put the string which is going to be the user id which is going to be coming from the asp.net user table which is automatically generated for us from the identity framework then we're gonna put the actual excuse me so we need to prop oops prop string this is gonna be the main jwt token which is going to be matching to the refresh token and then we're going to put prop string and this is going to be the jwt id which we're going to also be matching because if you remember here let me go back to the authentication controller we can see here that we're generating all the gti we're generating an id we're generating an ad so all of this when we can utilize so let's continue with this the next one is going to be a boolean to check if it's used or not because maybe someone has able to actually steal it from us and if we already use it they will not be able to use it anymore we want to see if it has been revoked or not so it's going to be is revoked so basically a user decided to broke all of their tokens when you want to protect them in case someone also tried to steal it and basically what we need to do here we need to add a date time to make sure the added date and we need to add an expiry date for the refresh token so it's also date time and we're gonna make it expiry date perfect so now once we have added here the next step for us is we need to go to the data folder and inside our application db context and here what we need to do is we need to add that table so our entity framework code will be able to pick it up generate a migration script and once it actually generate that migration script we can actually see that we're going to have a new table inside our database that we are able to utilize so what are we going to be doing here so after the themes so we're going to put prop data set db set we're going to call it refresh tokens let's use the first one and i think that's all the thing we need to do here and the next step for us is we're going to open our terminal let's see how if my terminal is big enough that should be fine and what we're going to be doing is we're going to put dot nut ef migrations add i'm gonna put add refresh token table and basically this will allow us to have a new migration script which is basically going to be responsible for creating the database for us the table for us not the database so now if we open our migration script uh let me add those and we open it here we can see that we have a table created called refresh tokens we can see all of the fields that we have processed uh that we have requested to be there everything is available for us and we can see that our primary key is going to be the id which is great so once we have done that the next step is we need to actually apply this migration to our database so it's going to be not ef database update so this should take a few minutes few seconds actually so now we can see it has been completed correctly so let's open this up if we take a look here let us refresh this so where's the refresh refresh refresh and we can see here we have a new table which is called refresh tokens and inside the table we can see that we have our id our user id basically all of the fields that we have specified inside our model is automatically added for us here which is exactly what we wanted so now let's close this and now what we're going to be doing is we need to start updating our authentication class so our sorry our authentication controller so we can start implementing the new refresh token functionality so now inside our authentication controller if we go all the way up what we need to do is we need to update our constructor to take advantage of these new items so first things first because we're going to utilize our db context we need to inject it here so we're going to put private read only up db context we're just going to call it underscore context and here we're utilizing dependency injections so we're able to utilize it and let us inject it here so it's going to be uh db context context oh really forgot the comma here and then we'll inject it here so the underscore equal contact so that's the first thing that we need to add the second item that we need to update here which is going to be the utilization the utilizat the token parameter verific the token parameter validation so let's add this so it's going to be private read only token validation parameters and we're going to make a token validation parameters and let's utilize this here as well it's going to be token validation parameters and let's inject it here equal token validation parameter perfect once we have actually added this a good thing to do is just do not build to make sure that everything is still building i did not mess anything up perfect we can see it's building and we get a bit succeeded we should yes build succeeded great so once we have done that the next step is uh let's go to our generated refresh token uh method that we have i think it was all the way at the end let's hide the terminal for now and this is the login and this is the generate jwt token so what we're going to be doing here is uh before we actually send the token back and we are actually writing the token so here we're actually generating it let's see where we get the best place to add it so here we're just generating it based on the id and basically if we take a look or where are we using it so here what we're doing is we are actually sending it back here okay so what we need to do first is inside this one here refresh token what we need to do is we need to generate this refresh token here and attach it so that's going to be our goal for now is basically attach this refresh token to this one so what we can do is whenever we have this generate refresh generate token we can just basically generate a create a new method which is called generate refresh token as well so we can utilize it so let's get to it or now that i think about it instead of having two methods what we can do is we can just have one which is basically return on author result with everything in so i think that's going to be a way better approach so let's update that generate jwt token to have that one so if we go here to that method so instead of returning a string we need to return an auth result and basically what we can do we can just put this var jwt token equal and then i think if we go back all the way up we can just take this one copy and i think here what we can do is we can update it to this so we can put var result equal and we can return actually without actually having to make it var results we can put return okay that should work do we need this nope we don't need this so i think now we are actually getting back a full object so instead of here uh trying to return it all we need to do is just return this one so we can delete all of this and just paste it like this so that way we are just trying to optimize our code a bit so instead of having different methods uh which basically gonna fit into the same object just out of like a bit of optimization organization so if we come now to the jwt generate token so let's also add the ability here to generate a refresh token so after we have the jwt token here being written we're going to be starting adding our refresh token information here so the first thing first is we need to define an object so it's going to go live inside our database for this refresh token so we're going to call it far refresh token equal new refresh token and we're going to input the information here so the first thing that we need to do is we need to put the token id which is going to be the jwt id equal token dot id that's the first thing that we want to do second uh let's input the actual token itself so yeah let's input the first token itself so uh token equal trade wt token and then let's see what do we have let's make this uh make this a bit higher is it clear yes to be clear so added date it should be datetime.ttc now expiry date so i think it's six months good for the uh refresh token so let's put datetime.utc.now.ad let's say months and we'll just give it six months uh so is it revoked no it's brand new so we're gonna put false is it used also no because it's still brand new so user id we're gonna get the user id based on the information that we have passed here so this should be user.userid perfect and lastly what is it what's id that's going to be auto-generated perfect so now that we have this the next step for us is we need to actually save it inside our database and once we save it inside our database we need to make sure basically let's save it first so it's going to be await underscore context dot refresh tokens dot add and we're gonna add the refresh token and then we're gonna put await underscore context dot save changes and then we see that we have issues here because we are drawing an async request for a method which is not async so let's convert that to make it async and let's make this as a task and basically we need to update the generator of this method here so this will be an awaits perfect and here also why is this complaining let's see add async okay perfect so now uh let's take this to the next step and basically generate our refresh token so basically something uh uh completely missed here so we should not put the token here this should be our jw i will refresh token so let's move this let's make this like this and here we need to generate a refresh token and basically here as well what we need to do is instead of returning an empty string we need to make a refresh token dot token and that way we can actually return the flash talking to the user so how are we going to be uh generating a refresh token what will what we can do is we can just generate a random string of characters that we can actually utilize and basically what we can do is we can create a method that's going to be responsible to create this random screen string based on our own decisioning or basically our own requirement and we can utilize this as a refresh token so let's add this method right now so maybe we can add it all the way at the end and let's create a method and we'll call it let's make it private first and it's going to return a string and we'll return it we call it random string generation anything we want and basically uh it's going to take the number of characters that we want to input so let's make it as an integer and we'll call it the length of our uh refresh token and basically we're gonna utilize the random equal the new random and basically once we utilize the random here we can just input the characters that we want to utilize to generate this random string so we can put a b c d e f g h g k l m n o p q r s t u v w x y is that i think i got this right it will be a shame if i didn't and then let's make it a bit of a lower character so again a b c d e f g n o p q r s t u v w x y is that okay and should we add underscores no let's leave it now let's add the underscore just to make it a bit more spicy so once we have done that the next step for us is we're gonna be basically returning the string which is gonna be a new string and basically we're gonna put innumerable innumerable dot repeat and we're gonna say that we're gonna be utilizing the charge okay why is this like this okay chars and then we're gonna specify the length of it so how many characters we want into it and then we're gonna put select and we're gonna implement the random in it so s dot random dot next and then basically we can put us dot length so we're basically doing random on the amount of characters that we wanted this characters in and then basically we're just making it as okay let's see why is this not happy oh why do i have a dot here i don't know okay and then lastly i need to just put a semicolon so return new string why is it still not happy because i did not spell it correctly return the new string all of that so let's take this one here and let's go back all the way up where we're generating our token you can find online a lot of method to create a random function i think this one i like the most and let's make our uh refresh token let's make it 22 characters 23 characters so i think now that we have done that let us just build it to make sure that everything is running so let's open our terminal and let's put dot nut build so that's going to be the first thing perfect i see it will succeeded plus from it now okay perfect it's running so let's go to localhost and let's try to register and let's name i'm just gonna call it uh let's say who do you wanna register let's say muhammad okay sorry i need to put on try it out name let's put muhammad one email muhammad one at at email111.com and password i'm just gonna put pass one two three i think that should be fine if i click on execute okay i got an issue because they are uh unable to verify the token by addition parameter that's fine let's fix this error right now okay so while i was trying to edit this video i discovered that i lost a lot of my previous footage because of some sound issues so i'm reshooting this right now and we're going to continue the video from here just an fyi if you see anything different within the video thank you for this and let's continue with the video actually let's reshoot the video okay so i think last time we were trying to do is uh basically i'm gonna stop where the problem has occurred last time and item as where i remember is we're trying to register uh a user so let's try to register this user for example and we were getting a dependency interaction issue okay first let's run the application to make sure that it's running okay great now the application is running let's try to execute this and if you can see we were getting this error regarding the dependency injection okay so the way we solve this is basically it's going to be very simple so after we do the injection of the uh of our sorry after we initialize our token validation parameters what we need to do here is basically just add to the the eye container so it's going to be builder dot services dot add singleton and basically we're gonna pass the parameters which is gonna be token validation params or token validation basically without this okay so all this is all we need to do so now let's stop this application and let us run it again and now if we go back to our web browser and basically if we try to register this new user you should be able to see that ania please verify your email perfect so that basically this makes us uh knowledgeable that the registration process is working so now i already confirmed this email let me utilize this uh to try to log in so let's go to that let's make some smaller uh this should be fine or yes it's um where is the login so okay so let's update the email address here and basically let's take the password and let's paste this and let's execute this so now we should receive a refresh token everything is working per plan so we've got the call we got the refresh token exactly as we wanted it perfect so now that we basically have we are able to generate a jwt token and now we are able to generate as well a refresh token so the next step is we're gonna actually include uh or create the action which is responsible for taking an all jwt token with the refresh token and return back to the user a new refreshed a new talk jwt token with a new refresh token and we're gonna add some validation on those methods in order for us to make sure that everything that we're doing is basically running from like validating was generating this talking the time is time so on so forth so let's get into it so let's go back to our rider let us stop this let us make this a bit smaller and let us go back to our controller authentication controller and let us basically uh start adding the functionality here so first of all we need to add an action so let's do this right now we're going to add it after that look and i will do it right here so the first thing that we need to do is basically we need to declare a new action so it's gonna be a post we're gonna make it http post we're gonna specify the http route http actually it's gonna be route not http route and then we're gonna say it's gonna call refresh token and then once that is done we're gonna put public async action actually public async task and we're gonna turn on i action result and we're gonna call this refresh token as well and basically we're gonna make it from body and we're gonna pass here the token request that we have created token request and we're gonna call it token request simple as that so so far nothing really uh complicated we're just creating a new action and basically we're defining the parameter for that action so the next step is we need to validate that the model of the token request is valid so we're going to say if uh view mode model state mode is model state dot is valid we're gonna continue else what we're gonna be doing is gonna basically generate the error and return that error so we're gonna say if errors actually it's gonna be return bad request and we're gonna return new both results and we're going to return let's say errors equal a new list of strings and we're going to return first one invalid parameters and then basically parameters okay and then oops parameters and basically once that's done also we're going to say the result is false and then thus should be it if it's the model said it's not valid else if it is well then what we need to do is we need to get far result equal basically we need to verify the request so what we're going to be doing is going to put far result equal verify generate tokens so that's what we're going to be doing we're going to verify the token if it's all good we're going to generate it if not we're just going to return an error and then basically we're going to pass the token request that we got and this we did not created yet we're going to create it after so right now let us just uh okay let us create this so inside after this what we can do is we can just do private async task and we're going to turn on auth result because that's we're going to be sending back okay it's not showing okay we're going to do auth results and this is it and it's gonna take token request i'm gonna call it token request as simple as that so so since this is gonna be a task and a uh let's make this an awaits and let us see here so if a result equal equal null so basically now we're just continuing uh the normal uh action without actually going through the verification that's going to be happen after so f result equaled equal null it means that something bad has wrong within the verification so we need to return a bad request so what we can do is you can just copy this and we're going to say invalid tokens no more nodes it's very simple to stay to the point else if everything goes to plan without the s we can just put return okay with the results okay now let's work on actually adding the verify and generate token so this is going to be the next step that we need to focus on because basically this is where all of the verification that we need to do all of the token generation for that refresh token with the jw tokens gonna happen so let's cut into it so first things first is we need to create a new variable and it's going to be jwt token handler and basically this token handlers are going to allow us to verify this token it's going to say equal new jwt security token handler and this is the first thing we need to do and then let's add a try catch basically we're going to be utilizing the try catch here in order for us to if there's anything with the validation uh happens we're gonna return it from there so basically what we can do here is something similar to first of all if you remember the errors that we were getting is regarding this item here which is the token validation parameters so we're going to be utilizing the token validation parameters in order for us to actually add the validation that we need to do so let's do it here so this is going to be the first item so we're going to put underscore token validation parameters dot actually validate lifetime value date lifetime equal false and then we're gonna say var [Applause] token in verification equal jwt token handler dot validate token and we're gonna pass the token that we had which is dot tokenrequest. and then here we can see that it's requesting that we need to pass back what is it where is it so okay so here if you can see from what is it uh method is expecting we need to pass the parameters and we need to pass the out token that is being utilizing so that's what we're gonna be doing so basically first of all we can pass the underscore token parameters and then we're gonna put out var validated token and that means that in case everything has passed we're going to have a varied token to utilize if not we're going to basically have a fade validation and basically we are utilizing the refresh token or basically the token validation params that we had before in order for us to pass it here something that we can do i added this one just for testing but basically what we need to do is uh when it comes to actually validating the lifetime this needs to be enabled but just for the sake of testing we are made as false but other than that it needs to be true so this is something that we need to be wary of we're going to disable it later on but for now we just made it false so we'll make our life a little bit easier when trying to debug stuff after we finished creating this method so once we have added this the next step for us it's going to be basically continuing the validation and we're going to have different types of validation that we need to implement and there's going to be different rules so let's gonna go through it one by one so the first one is going to be basically uh let's say if we need to make sure is the validated token is out so it's gonna say if validated token is j jwt security token and we're gonna make it say wt security token and basically here we're gonna put fire result equal jwt security token dot header dot algorithm dot equals why is it like this equals dot security algorithms dot hmac 256. so basically right now here if you remember when we're creating that jwt token let's go back and let's see it where is the generate okay if you look at here the security algorithm that you utilize to generate this token we are utilizing hmac 256. so one of the first thing that we need to validate when we're actually receiving this token is it's actually being uh utilizing the hmac 256 that we have fast because if it's using anything else on hmac it means that's not the token that the system has generated so that's going to be the first thing and then we're going to put a string comparison dot ignore what is it okay invariant culture and ignore cases so that's just to make sure that no matter from where we are safe and then basically once we compared if that security algorithm that we are utilizing is matching the security algorithm that you utilize in order for us to generate this token so based on the result so if result equal equal false so we need to return model because basically uh this this token is invalid and basically this token is using different security algorithm so we cannot continue to generate the refresh the jwd token from the refresh token so that's going to be the first thing so the second thing second check that we need to do is we need to actually uh validate the expiry time of the token that we currently have so and there is going to be a lot of a lot of items that we need to do so let's get started with it so the first thing is we're gonna get the utc excuse me so we're gonna put fire utc expiry date so we need to get the expiry date of that token equal because it's going to be utc types it's going to be long dot parse and then basically from the token verification token and verification uh we're gonna put claims dot first or default and basically what we're doing here is from the claims that we currently have is we're gonna get the specific claim that we have utilized to generate this token in order to see when was this token generated again if we take a look up before we continue with this if you remember when we generated this token we basically added claims and you can see here from the claims we are basically adding the yacht which basically when was this uh claim has been generated or basically has been created and we can see here is we're utilizing their universal time which is the utc time and based on that we're gonna get that yet and basically we're gonna try to compare it with the current time that we have so let's go down let's go down here i think this is it yes and basically from here what we need to do is we're going to be utilizing the type of the claims that we have equal jwt registered claim names dot expiry i think uh we're going to get the value let's make sure that it's the same thing is it expiry or yet when we generated that token let's check okay let's add that one here so let's copy this oh okay we already have it here the expires apologies security descriptor yeah so we already have the expire here so we can utilize it we don't have to really add it okay great so basically once we check this one the next step is we need to get the current time in order for us to match it so far equal expiry date equal unix time stamp to date time so we're gonna basically convert this unix timestamp into a certain daytime that we can do comparison on and this method does not exist we need to create it so we're gonna pass here the utc expiry date and basically what we can do is after this method we can just create this one and it's basically it's going to be something very simple and it's going to be something like private date time and then return date time it's going to call like this and it's going to expect a long unix timestamp and basically what we're going to put is var date time val equal a new date time and basically we need to make it from the 1970s because basically this is where the next time stamp so it's going to be 1970 not 60 70. yeah and then it's going to be one one oops one and then we're gonna make it the zero zero and now i think it's the second zero and then we're gonna put uh one two three at the last zero here for the calendar and then we're gonna put the sorry for the millisecond and then we're going to put the date time kind that equal utc so basically here what we're doing is we're going to the 1970 first of john and we're doing zero zero zero 0 and we're basically telling it that this time valuable is going to be within utc because basically utc is every single second from that from 1st of jan 1970 0 0 0 up till now so what we need to do is we need to get that time in utc and then basically date time sorry and we need to do this comparison so now what we can do we can put just the time val equal date time val dot add seconds and that's basically we're gonna add the number of seconds that we have and this is going to be the unix timestamp because basically earnings timestamp is a number of seconds from the 1970 so we're getting the date of 1970s we're adding the seconds to it and then we're gonna convert it to our universal timestamp and then we're gonna put two universal time and then once we have that we're just gonna return it day time valve okay perfect so now that we have this let's scroll back up where was it here so once we have this now since the expiry date since we got now the expiry date and date time which is exactly what we wanted we can actually do some comparison on that date time to make sure that it is within the time frame that we are expected to do so here what we can say is if expiry date is bigger than date time now date time but now [Applause] it means that it not now okay it means that we're gonna be returning auth results and we're gonna say inside this that success return a new auth results and we're going to say here that result equal false and then we're going to say that the errors equal new list of strings and basically this is going to be expired timestamp expired token simple as that because basically the token that we have has been expired so this is gonna be the second check or third check that we're gonna be doing the next check is gonna be basically on the actual token itself so we're gonna basically check if actually exists in our database or not so we're gonna say var stored token should be one word equal await underscore or db context what was it called context dot refresh tokens dot first or default and we're gonna be basically matching this on that token that we have token equal equal to the what did we call it here token request equal token request dot token dot refresh token and then basically once we have that we're basically gonna async uh once we have that first we need to check if it's null or not so if uh what will be called stored token it could equal null we're gonna say basically return but so here just remember sorry return bad request and inside this bad request we need to put this return bad requests oh no apologies this what happens when you try to really shoot a video that you have already showed it before so return new auth results and basically this auto result is going to contain the result which is going to be false because there's an error and we're going to let's copy this and we're going to say invalid tokens but i would not want to give more information invalid tokens as simple as that because basically what we did here is those tokens that we currently have with our flash talking does not exist so it means that it's not a valid token and as we saw previously that the refresh token that we are generating are custom based on our method that we created here which is called the ch what is called it's called random string generation so this is why we have utilize in order for us to generate the token so that's why we need to make sure that actually exists in our database so once we have checked the stored token that is actually exist now we can run some checks against it and to make sure that it's a valid one so now that we have checked this the next one is going to be if the store token dot is used because base default is not used so we can return this as well because we don't want a used refresh token so invalid token as simple as that then we're going to make sure if it has been revoked so if store talk and dot is revoked we're gonna turn the same error because basically if it's used or if it's revoked we don't wanna use it and then basically we need to utilize right now the gti so if you go up here and if you take a look at the code that we have utilized to generate the tokens we can see here that we are utilizing a gti and basically that's going to be a unique id for that token so we need to make sure that it exists for the jwt token so that's another check that we need to do here so let's get that so far gti equal token verification token verification dot claims dot first or default and basically we're gonna go through the type again equal equal j w j w t registered claim names and gti dot value and basically what we're going to be doing after this we're going to say if store token dot jwti not equal to the gti it means that it's not something that we have generated so we're gonna say invalid tokens again because we don't really want that because if you remember let's open the refresh token table we are still we are storing here the jwt id and basically jwt id is what we are is the unique uh good that we have whenever we are generating agenda bt talk and this needs to be unique and exist in our tables and belong to the same refresh token so that's why if in in case it does not match we cannot freely process uh continue processing the request so once we have checked the gti the next one is gonna be actually the expiry date of the refresh token so it's going to be if store token dot expiry date is glass then date time dot utc now date time time dot utc now utc now so in case it's lasts we're going to also return this similar result and here we're going to say expired tokens and then once we make sure that everything all of these checks has passed now we can actually generate a new token because we made sure that the token is not used it's not revoked it belongs to the same id of the jwt token we made sure that it's within the uh certain time frame of the generation of the token that it's actually valid we made sure it's utilizing the same security authentication so all of these checks we have made sure that we have added everything has passed now that since everything has passed we are basically able to uh start generating a new token from the user so it's very simple first of all we need to update the current store token to make to basically make sure that it has been utilized so is used is gonna be true and then we need to save it inside the database to make to make sure that we cannot reuse it again so we're gonna put uh await underscore context context dot refresh tokens dot actually we can just make the save changes don't tell you what refresh tokens dot refresh tokens dot updates and we're just gonna pass the store token update async oh there's no async okay so let's keep it update and then we're gonna put await underscore uh context dot save changes async and then once we have done that the next step is we need to actually start creating this token again and basically we're going to put var db user we're going to have to get that db user based on the jwt token that we have it's gonna be await underscore user manager dot find by email async or basically we can find it by user id because we already have that user id so we can find by id async and we're gonna pass the stored token dot user id so that way it makes it easier for us because basically in essence whenever we got the start token from before that store token that we currently have is gonna be responsible to actually uh it's gonna store the information for us so if we take a look here sorry not this one inside this one oops if we take a look here we can see that we are storing the user id so that's a good way for us to get the user id and generate a new refresh token and what we're going to be doing is because we're basically reusing all of the functions that we currently have we have a function that is automatically responsible for generating the refresh token so we're going to be utilizing that so we need to pass the db user for it so we're going to put return await generate jwd token and if we take a look what does it expecting is inspecting the db user that we have and that should be it because if we go to this one to this method here and we can see it's basically expecting an identity user and it's doing all of the magic to create for us a new jwd token under flash token so we don't really need to redo the work all over again so once we have done that let's check here what's the error that we're still getting so oh we need to add a validation here so in case something goes wrong we're just gonna say server error so in case anything happen while we are trying to actually re-authenticate the user or basically for any reason there was a server error instead of just giving a 500 we're catching the error returning to the user that there's a server error so let's do this so let's do not build and now after this we can actually test the our code and like we can see here that it's passing oops where is it we can see that the build has succeeded and now we can actually start testing our code and make sure that everything is working as it should be so let's start with the testing for now so let's go back to our web browser and basically let's keep this username and password so we don't forget them so copy this and thus refresh this page we did not run it application let me run the application the application is running perfect so let's go here let's refresh this perfect now let's try to log in where is the login this is the login try it out let's pass the using email and password execute perfect we got the token and the refresh token so let's take these two copy them and basically we're gonna utilize the refresh token so we can see here that this is what expecting trying it out and just to make sure that it's working as it should be let us go back to our rider and in that action itself let's do a break point where is it so this is verify this should be here perfect now let's just go back and let's execute this request and what did we get we got a 400 and refresh token is field is required oh apologies uh i think i did the typo and let's see okay refresh token this is what is required oh it should be refresh token and this is gonna cause problems here so let's fix these issues so here should be refresh tokens i'm not sure if you can see it yes you can let me fix this anything else there's another one here that we need to fix or that should be it so let's try run it again okay it's running that's great now let's go to our web browser and let's try to execute it perfect we hit this endpoint and let's see if we're receiving the information correct yes refresh token and the token let's continue it is valid and now let's check the token validation okay it should be fine all of this let's go in okay i think it's gonna it went to a different tangent so let us go to declarations and let's put a breaking point here until it reached this end point and we got a new token with the refresh token that's what we were expecting but okay let's generate a new one so let's take this one this is where from the login nope that's correct so let's take these and let's send a new one so we can actually check the verification so inside of here i'm just gonna paste this new ones and i'm gonna send a new execution so we let's stay here the end of the refresh token add with sr9 so that's we need to worry off uh whenever we're generating we need to get a different refresh token and for the token itself we can say it's ua5 we need to get a different one so let's execute and okay okay we have added an extra comma that we should not have added let's check this perfect we should not have this comma here let's execute okay it reached this point it reached this end point here so let's see first of all the validated yes we got all of the information for that validated token we can see the user that we have been utilized let's take a look at it we can see that gti you can see the id we can see the sub we can see the security algorithm everything that we want is already here exactly what we wanted the first validation has passed the second validation regarding uh let's check this one so the result is true so it means that it is equal so that means the first one has passed now let's check the expiry date we got it in the utc time so now we are converting it to an actual time and we can see it expires today yes today at 4 32 perfect way more than now so let's continue with this the stored function perfect we're getting it it's it's stored inside our database yes it exists uh is it used should be false it's revoked should be false and basically the gti it should be matching that check it is matching the expiry time is valid we're updating it and basically it's generating a new token and it is returning to us perfect so now it worked the first time so the second time that we need to do is we need to execute it because it has been already utilized we should get an error so let's test this out so let's click on execute and let's continue with this so this validation has passed the security algorithm the expiry date should be fine because we gave it a lot of time is it used now we should receive this as true so let's see perfect so we said invited token because basically right now if we take a look at the response we get an error and we got an invalid token because this token has already been used perfect so now that basically what we have done is we have covered all of the validation scenarios that we currently have for our tokens we have went through the generation of the jwt token we have attached the refresh talk into it we have created the database table for it as well we went through the entire process of validating that refresh token with the jwt token so i hope this video helped please like share and subscribe if you like this video uh it will really help the channel please put your questions in the comments down below and we'll try my best to answer them and help you with them uh again this is a really important topic to understand how refresh token works because basically it is really important for us to have the best user scenario or best user interaction with our application and basically if we're creating a web api it's really important for us not to ask the user to log in every couple of minutes we need to utilize the security talk the jwt token with the refresh token to get a brand new security token so we can continue the user journey and make it as easy as as possible for the user to enjoy our application without us having them to actually authenticate every so often again i hope this video helped and have a great day
Info
Channel: Mohamad Lawand
Views: 16,367
Rating: undefined out of 5
Keywords: asp.net core, jwt authentication, json web token, .net, api, .net 6, beginner guide, step by step, csharp, c#, dotnet, dependency injection, code with me, coding, ef core, sqlite, database normalization, database, entity framework c#, entity framework core, entity framework, asp.net core tutorial, asp.net mvc tutorial, net core mvc, refresh token jwt, refresh token, api refresh token
Id: 2_H0Zj-C8EM
Channel Id: undefined
Length: 96min 32sec (5792 seconds)
Published: Mon Jul 18 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.