 Are you protecting your APIs correctly? Let's say you've been working on your API and found out that you want to protect some of your endpoints from unwanted requests. In this video, I'm going to walk you through all of the steps that you need to protect your fast API endpoints using R0. Protecting your endpoints will guarantee that only parties with a valid access token can access those endpoints. In this case, an access token will be provided by R0. To use R0 to protect your endpoints, you need to first create an API in the R0 dashboard. And second, update your code to validate the JOT access token you will get from R0. Let's see how that works in practice. To get started, you need to grab our fast API sample from GitHub. Or you can use an API that you built within points that you want to protect to follow along with the steps that I'm going to show you on this video. If you want, you can skip ahead to the time codes outlining in the video description below. Let's clone the project. And the link for it is in the description below as well. After you clone it, open that up on your favorite IDE. Now, I already have that cloned here. And I'm going to be used VS Code. So that's what I have open here. Let's create a Python environment and install all the dependencies listed in the requirements.txt file. And notice I'm using Python 3 here. Now let's activate this environment. And I have a shortcut here that I can use. And it is activated. Now let's install the dependencies with pip. And first, I'm going to update pip. And after that's done, I'm going to install everything from the requirements.txt file. And in this file, we will include all the versions for FastAPI, UVCore, and the asynchronous web server, and PyTWT. These are all the packages we are going to need to actually run this simple API and validating the Jot access token we're going to get from Auth0. Now that that is done, let's run the API and check out what is going on. So to run this, I'm going to use UVCore, application.main. That's why my routes are implemented and going on over to the app. Now that that is done, let's run the API and check out what is going on. And the comment for that, let me clean up my terminal and run it. And once this is started up my server, I can check out the documentation for this API. Because I'm using FastAPI, I can access the slash dots endpoints and can see the documentation for my API. So if you go into your favorite browser and type localhost, port in the docs endpoint, this will load my documentation. And this API only has two endpoints, a public endpoint and a private endpoint. And before we look at the code for each of them, let's make a request for each of them. So let's start with the public one. And I can see here the documentation for the public endpoint that comes from the doc strings from the endpoint definition. And if I click try it out and execute, you can see that I made the request. I get request to this endpoint. And I can see the response. And it was a successful request. Now, if I do the same thing for the private endpoint, you can see also here the documentation for it. And if you scroll down, you can see a little bit of the responses you might get. So let's try this one out. So click try it out again and then execute. And this also made a good request for the private endpoint. And you can see here that I actually get a success for this request, the same as I did for the public endpoint. And that's because even though this is a private endpoint, it is not protected yet. And that's actually the one endpoint we are going to update today. Now we need to configure your API on the R0 dashboard. Let's do that. And I already logged into my R0 account here. So let's create this API. And the way to do that, you navigate through this application option on my left-hand menu. And then you click on APIs and there you can see a list of your available APIs. Everybody will have the R0 management API. For example, and any other API you might have configured already. But if that, that's okay. Let's create the API we're going to use for this example. And you can click on create API on this button right here. And finally, you can give a name for your API. Now you can see here that I have a few names that I tried in the past. Those are all examples that I was working on, especially one for this same video. So let's use the name that I already have here. And you can change the name later if you want to. But one good tip is always have a very meaningful name so you know which API you have. Because once you have more APIs under your dashboard it might be hard to find the one that you want. Another thing that we're going to do is set up our identifier. And this field cannot be modified later. So choose carefully. And same thing, I'm going to use a very meaningful one called FastAPIoutZeroExample.com. And I'm going to leave the sign algorithm as the RS256 that is the standard and is a very safe algorithm. We're going to want that. So let's create our API. And once you click create, after downloads you'll be taken to your API page. And now we have our API is configured. You don't need to do anything else on the OutZero dashboard. And now that we have this set up, it's time for updating our code. And the first thing we are going to do is actually create a config file. And this file will hold all the API information that we just created. In this simple project, there is an example config file that you can use. So let's copy that and paste it. And let's update first the name. Let's rename it. Let's leave it only.config. And update the contents of the file itself. Let's update the values for our information. And my domain is actually my tenant domain. So if you don't know what your tenant is or you forgot, you can just go back into your dashboard and you can look here. Once you click on your name or your tenant name, actually, you can see that my tenant is actually Justin Peral, which is my name because I'm not very creative about that. And it is located in the United States. So that's our part of our domain. So let's go back and update this by doing JustinPeral.us.out0.com. And the API audience is actually the API identifier. If you don't remember the identifier that you chose, go back into your Out0 dashboard and you can find the identifier right below the name of your API on your API page. And just copy that and place it on your audience. And your issuer will be similar to your domain, just prepare the HTTPS part. So let's copy this part and update here. And now we got everything that we need from our API configuration. Let's save this and close this file because we don't need that anymore. And this information will be used later in the process for verifying the access token. Now, before we move on, I like to point out that this code is ready for using either a config file or environment variables. So you can check out how to use that, either one or the other, on the rhythm of the project. With that said, let's update the endpoint code. And to do that, you need to open up the main.pli file. One thing that you might not know is that FastAPI has a dependency injection system that we can use to implement all the security flows in our applications. And this dependency injection system as FastAPI documentation states actually is designed to be very simple to use and to make it very easy for any developer to integrate with all the components with FastAPI. And that's exactly what we are doing here. We are integrating our zero with our API. Among other things, the dependency injection can be really useful for minimizing code repetition and enforcing security, authentication, and role requirements, for example. Now, let's see how we can do that with code. So here I have my best code, as you know. And we can see here, both of my endpoints definition, right? We have a public one. And we have our private one. But let's import all the dependencies we're going to need to actually protect our private endpoint. And let's start with our depends class. That's going to be responsible for the dependency injection part. We also need the response. And that's capital R and the status in case we need to update the status of our response if something goes wrong, right? We are also going to need to import from the security module from FastAPI. And we are also going to need the HTTP barrier from the FastAPI security module. And now that we have everything, the first thing we are going to need is actually to define the instance of the HTTP barrier class. And that will be our security scheme, the one that we are going to use. And that's because we're going to use that scheme to make sure that we have a better header on the request. Now let's create that instance. And I'm going to call it a token underlying off, underlying scheme. And that will be HTTP barrier. And it is an instance. Cool. The way we are going to do this is by adding a new parameter to our endpoint function called token. So let's scroll down. I'm going to hide this code for a moment and add a token here. And this token parameter will be very special because we are going to use the depends class right here by passing our scheme to the depends as the value of our token. So let's update that depends and add the token of scheme. And let's save it. Oh, it's missing a type. And let's leave it as string and that's the depends value. Now, before we see how this change affects our endpoint in the documentation, for example, is important to understand what is going on here. So this is how the dependency injection system in FastAPI works. You are going to pass either a function, a class or instance to the depends class. In this case, we are using the HTTP barrier instance. And then every time this endpoint receives a request, FastAPI will evaluate the dependency clause and run the function or class against the request. And finally, we return the results of that operation to the parameter. Now, let's take a closer look at the documentation now. First, I need to stop my server and we run that. And once that is done, I can go back to my documentation and refresh it. Now that I have a refresh documentation, you can see that something changed here. The first thing is that we got this authorized button right here. And that's because this means we have an authorization process that you have to do to access some of our endpoints. With the same button happens to be showing on the private endpoint now. And that's because this is the endpoint that has security measures. Actually, a few security measures. So if I click either one of these buttons, I'm going to click this lock it here. You can see this form comes up. And this is telling us that we need to provide an authorization access token to actually do a request. Now, keep in mind that this alteration that we just did doesn't validate the access token. It only checks whether or not there was a value provided in the better header of the request. So first thing, before I change anything, let's close this and let's try to do requests without providing any value to that authorization form. So if I execute, you see that now we got a forbidden here because of course we didn't provide an authorization access token. Now let's try to do something different. Instead of not providing anything, let's try to provide something weird, some random string. For example, FastAPI is awesome. If you watch my previous videos on JWT, you probably know this is not a JWT. And if you know how to do it, you also know that this doesn't look at all as one of our access tokens. So if I try to use this and authorize and close, you see that I provided the FastAPI is awesome as a better token in my authorization header. And I got a success. And that's because, well, like I said before, we are not validating our access token, but there is a way that we can do that. Let's see how to do that. Let's go back to our code and actually add a step that validates our job access token. And here's a little tip. There is a number of ways that you can actually validate an access token, especially in Python, that is a number of options in libraries out there. And if you need to understand a little bit more about JWTs in general, I have two linked videos right here that can be useful. But to make your life easier in this project, that is a file called utus.py. And in this file, we actually have a verified token class that you can use to verify your tokens. And feel free to copy that and use it on your projects. Now, I'm not going to explain in detail what the verified token class does, but in general lines, it deployments all the steps necessary for verify a JSON web token provided by Auth0. And if you want to understand in more detail what are the steps and what you need to do to verify a JSON web token, I recommend you read the Auth0 documentation on it that is linked in the description below. Now, let's import the verifying token class into our main.py file and actually verify the token from the request. So the way to do that would be like this. First, I'm going to import my verified token class. And I'm going to do from utus import verify token. Thanks VS Code for auto completing everything. And the way the verified token class works is like this. You're gonna pass the token from the request to the verified token class by calling the token.credentials. And you need to call the doverify method from the same class. And if the verification process is successful, you're going to get the payload from your token. If not, you're going to get a dictionary that we have the details of the error and I started saying that something went wrong. So let's do a step for grabbing the token credentials and saving the result of the verification process inside of a variable. And I'm going to call the variable result as well. I'm going to comment this result out because I don't need it anymore. And result is going to be, well, the result of the verification process that validates my access token. And I'm going to do token.credentials and call the verify method. And now this will be the result. Another thing that I want to do is actually add a step and give a detailed response in case something goes wrong. There is a number of ways where you can do that. I prefer to do get from the result and I need to get the status key value. And if the status key exists on my dictionary, it means something went wrong. After that, I'm going to return the result with the error message result. But I also want to do one thing. I want to update my response to actually display a status code that corresponds to an error. And to do that, I need to actually have a response in the signature of my function. And that's where the response that we imported earlier on comes in. And comma, and now everything is done. And I can use the response now inside my verification step. And to update the status code, I just call response.status code. And then I can use that status. And status actually has all the status codes that you could use, the most common ones. And let's just give a bad request as an error for the time that we will suffice. And now our code is actually done. Awesome. Let's save this. And finally, let's rerun our server and make a few requests because, well, I want to see this thing work. Let's go back to our documentation. And I'm going to refresh this page. You can see the authorized locket is open. Which means I don't have an authorization value for my authorization form. First, let's see if the public endpoint is still works just in case. Let's try it out and execute. And everything works awesome. We got the success response. Awesome. Now let's go to the private endpoint. And let's try to do a request without providing a value for the authorization. And if we execute, we still get the forbidden error, the four three, awesome. And let's provide some random value again. Fast API is awesome. And if I click authorize, I can close this form now. And if I execute, our request got updated. I have my authorization barrier here. And now we get a bad request. Not enough segments. That's because that fake JWT that we use actually doesn't have enough segments for to be considered a valid JWT, which makes sense. Now, we can do another task, which would be grabbing a random JWT from our friendly JWT.io. And that JWT actually is the wrong type of signing algorithm from the one that we expect from the Auth0 API. Now, if I click on the locket once more, I can log out and add this new JWT value and authorize, close it. And if I execute, it is loading. Okay. And now you can see here that I have the JWT token I copied from JWT.io. And you can see also that we have a bad request because it couldn't find a signing key that matches none. Of course, HS256 doesn't use signing keys, it uses secrets. So there is no signing keys there to match. So let's do an actual request, that one that is going to be successful. There is a number of ways we can do that. You could go back into your API page on the Auth0 dashboard. And after that, access the test tab. That's where you can grab either the request you need to do to have an access token or the actual access token for your application. Now if I scroll down a little bit here, you see I have an access token here and I have this amazing copy token button here. And if I copy this, I'll have a new token that I can use in my documentation. Now let's authorize the new token by logging out from the old one. That's the incorrect one and paste the correct one and do an authorization. And close and execute once more. Now this new token is a longer one you can see here and our response body is successful. Yay, you can see here my tenant name and you can see also my audience and everything works. Voila. You just performed a successful request to a private endpoint. Congratulations. If you watch it until here, you'll now know how to protect your endpoints. And if you have any questions and want to see more videos like this here in the channel, leave a comment down below. Also, remember to subscribe to the channel and check out the link section in the description of this video. There you'll find a link for the sample I used and the blog post on the same topic written by our guest author Mark Hoping and the documentation for the steps you validate JWTs. Thanks for watching and I'll see you soon. Bye.