JWT Authentication (Revoke Access Tokens Using Redis) - FastAPI Beyond CRUD Part 12

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's up everyone welcome back in this video we're going to be looking at how we can revoke tokens on the server side in the previous videos we looked at how we could allow users to have access to our application by using their access tokens we also looked at how they could regain their access when their tokens are expired by using their refresh tokens now in this video we're going to be making use of radis which is an inmemory data store to help us act as a block list for the tokens that we shall revoke on our server site now if you to look at my rests right here I have this error which is an internal server error and this error is occurring because we are trying to make use of unexpired token to refresh our token so the problem is that we are having an error or a bug or an issue that I left in the code in the previous video and that is arising from this check where I was checking if token is valid so if you check this is calling the method token valid but it's not taking the token that is going to be checked so in this case we've decode the token and after decoding the token we go ahead and check if its data is n or not so what I'm going to do is to first of all fix this error by providing the token so if you try to access this with an expir token of course we shall get our exception being raised so let's go ahead and now set up our radius client so right here in my terminal I'm going to begin by installing IO Rus which is going to be our sync IOP client for radius and what this is going to allow us do is to access the different methods to interact with radi from our python side so I'm me say pip install and in our case we're going to say iio radius so this will go ahead and collect I radius and add it to our virtual environment after which we shall now go ahead and create the red client and and then use that client to interact with red so if I go back to my Cod right here I'm going to go to my DB folder and inside here is where I'm going to create a file which I'm going to call rpy and this is where we're going to write the code that's specific to radius now that we have our radius installed let us go ahead and Define some environment variables that are going to help us access R so we shall Begin by adding those to ourv so the first one is to be our R host and our R host in this case is going to be Local Host now another thing that you may need to set up is going to be our radi sport so our R sport is going to be 6379 and once we've done that then I'm going to go ahead and copy this two and I'll head over to our config because we need to access them from ourv and add them so that we can access them via our config object so I'll just go ahead and simply copy this now I can go ahead and simplify this by saying that our radius host is going to be a string and also our R Port is going to be 6379 but it's going to be an integer so what we have here is we're setting our port to be 6379 in case we haven't provided a port but that Port is going to be an integer we can do the same thing right here by simply saying that in case we do not provide our R host then our host can be Local Host and this is going to be a string so let me go ahead and make it one so once we've defined this then let's go ahead and set up our radius client object so in head over back to our rusp inside our DB folder we shall first of all import iio radius by saying import IO radius once we've imported I radius then let's go ahead and also import our config object so we shall say from source. config we shall import the config object once that is imported then we're going to go ahead and simply create the red client object so we're going to Simply call this the Rus token block list or let's just actually say this is going to be our radius token block list or we can simply call it our token block list so we shall say token blocklist and this token block list is going to be the object created from radius so we shall say I Rus and shall make use of the strict R object and inside here we need to go ahead and specify the host so our host is going to be our local host but that's going to come from our config do Rus host and then we're also going to provide our Port so our port in our case is going to be from fig in this case we're going to have our radius port and once we've done that we can also specify our DB so our DB is going to be DB Z and this is going to be our config for our radius so this is just enough for us to get a connection to our radius now we need to Define two functions one is going to be to help us add the token to our Black List and another one is going to be the one to check if this token exists within our block list now we're not going to be storing tokens but rather we're going to be storing their jti or our J WT that we set up when creating these tokens so to do that we're going to now say a sync and this is going to be add jti so this going to be add jti to blocklist and this is going to take in the jti which is going to be a string we don't expect this to return anything so shall specify the return value to be n and in our case we shall just have to come right here and simply await iio radius or our token block list so in this case we shall call the set method now this set method is basically one that helps us to a value using a certain key so it works in a way that we provide the key and then provide the value and the expir or the time we want that value to expire so in our case we're going to come at the top of our code right here and then we are going to specify our access or our token expir let's just call it the token expir so in our case oh this is actually our jti expir so I'll just set it the jti expiry and this jti expir is going to be let's say after 1 hour so we can go ahead and set this to be 3,600 seconds and then uh asset here is going to take in our expiry which is going to be our expiry time so it's going to take in the key it's going to take in the value and then it's going to take in the expiry so we're going to go ahead and set that up by coming right here the name of the key is going to be equal to R jti and then we do not need the value so we can leave the value to be equal to an empty string now for the expir we're simply going to go ahead and set it to be our expir here that we've said so that's going to be our JWT expir and once we've done that this function is just enough for us to go ahead and add our token to our block list or jti to our block list another we're going to carry out is want to check if our token exists within our block list so to do that shall just come right here and say a sync and this is going to be def token in blocklist so this going to be block list and this is going to just take in our jti which is going to be a string and it shall return Aban once this is done then we shall simply call add token block list dot in our case shall say get so this is going to take in the key which is going to be our GTI and we can actually call this our jti so we need to check if this jti exist within our radi and once it doesn't exist then we shall return true or false so to do that shall just simply come right here and say return jti is not n so this can return true or false depending on whether the JT is not none so I can go ahead and do the same thing for every time I say is not none so for example instead of saying return true if token data we can just say return token data is not none and that will just be enough for us to return whether our token data is true whether our token data is not none or is none so returning token data n will return true if it's not n else it will return false so just to avoid that repetition so once we've defined these two methods let's go ahead and make use of them within our dependency so to do that what I'm going to do is to head over to our dependency and at the top right here I'm going to begin by importing our function for checking whether the token exist in our block list so I'll just do that by coming at a top right here and saying from Source do DB do radius we are going to go ahead and import our token in block list once that has been done then let's go ahead and simply add this check within our call method so right after checking if our token is valid then we're going to go ahead and also check if our token is in our block list so shall shall come right here and say if in this case shall call await token in blocklist because this is an awaitable or a COR routine then this is going to take in our GTI so that's going to come from our token data so shall say token data and in our case since this is a dictionary shall access the jti and once you've accessed that then we're going to raise an exception so I'll copy what we have here and then I'll paste it right here so once we have this then we can simply go ahead and provide the detail so for our case we're going to provide the detail having the error and our case our error is going to be this token is invalid or has been revoked another thing is going to be what the user is going to do in case they get this error so we shall just give them a hint of how to resolve the error so we're going to call this the resolution and in this case shall tell them to get a new token so shall I'll just simply tell him please get new token and this will be just enough to throw that error another thing we're going to do is to Simply add this to our to our invalid or expired token detail so I'm just simply going to change the way I return these errors by using this format so I'll just give them a hint also here I'll just tell them that their token is invalid or expired and I'll just tell them to get a new token so this is now going to be a little bit more detailed than simply saying invalid or expired token so we now see this token is invalid or expired and please get a new token which is better so once that has been done then the next thing is going to be for us to implement the end point for revoking a token now I'm going to go to our o routes and inside here I'm going to create a new route by calling our Au router so in this case we can choose to use a post request or get request or whatever so I'm just simply going to keep it to a get request since we're going to pass our token in our head the token that want to evoke so in this case I'll call this our end point which is log out and I'm going to Define this as a sync def then shall call this Handler revoke token now this is going taking our token data our token details and this will be making making use of our dependencies now what I'm going this to import our access token Bearer as it's going to give us the details of the token that we want to go ahead and revoke in our case shall come right here and say access token Bearer and this is actually going to be a depend so this will be a dictionary and it's going to be a dependency so we're going to make use of our depends function and when you've done that then you shall provate the dependency which shall be an object of our token Bearer and then inside that is where we're going to get our jti so to get our jti shall say that our jti is going to be token details and in our case shall get our jti our token details will be returned as a dictionary contain in the claims that we submitted within our token and once we've got that as a dictionary then we're going to go ahead and grab the jti once you've grabbed the jti then you're going to make use of this function to basically add token to our block list so to do that we're going to import our function by saying from Source dot in this case it's going to be db. tradish then we're going to go ahead and import our add token or add GTI to blocklist so once we have done this we're going to Simply come right here and say await add JWT to blocklist and in this case shall provide our jti and once that has happened we shall simply return our Json response and add detail in this case or our content is going to be equal to a simple message of loged out successfully so we simply come right here and say logged out successfully so we also going to provide the status code and that's stus code is going to be equal to status do HTTP 200 okay this is enough for us to log out a user so let's go ahead and test it out shall go back to our Forks right here and shall create a new request and this request is going to be one for revoking tokens so I just simply say revoke access tokens so inside here is where we're going to provide our URL so in our case our URL is going to be on the SL logout endpoint or the SL log out path try to get this we are not authenticated so we need to provide our header I'll add our header which is going to be our authorization header and in here we shall provide beer and then the token so our token let's go ahead and create a new JWT pair when you try to get this token and use it to maybe get all our books shall provide this token right here to help us get our books we can get our books but when roke it in our case we shall just send it here so we have an error we try to see what this error is we're being told that red. set got an exp an XP argument so it seem like we are wrong there let's go ahead and check it out if I go back to radius uh radius. set simply has to take in ex not exp sorry for that if I provide that when you try to make this request again we see that our user has logged out successfully which I called our so let me go ahead and also fix that so we shall say that our user has been logged out successfully and when you try to make this this access token make request shall now see that the token is invalid or has been revoked and therefore we need to get a new token so that means that our token is added to our block list and we cannot use it to access any other endpoints on our API so if you try to let's say create a book using the same token we're going to notice the same thing that this token is going to be added to our block list and therefore we cannot use it to make any other requests to our API endpoint I hope you've enjoyed and learn from this video if you've done so please leave a like it helps the videos in the algorithms do not forget to subscribe if you're new and I'll see you in the next video bye
Info
Channel: Ssali Jonathan
Views: 334
Rating: undefined out of 5
Keywords: fastapi, fastapi tutorial, jwt auth fastapi, jwt authentication, fastapi course
Id: e954e-i5DgQ
Channel Id: undefined
Length: 17min 54sec (1074 seconds)
Published: Fri Jun 21 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.