3.3 Secure the API
Our API is publicly available, but we need to limit access to the
DELETE methods. In this lesson, you'll learn how to use Lumen's built-in authentication middleware to secure the API.
1.Introduction2 lessons, 06:28
2.Create a Sample API2 lessons, 17:23
3.Write the Music Store API3 lessons, 27:11
4.Conclusion1 lesson, 01:04
3.3 Secure the API
Security is a very important part of not just a web API but in the application. And unfortunately, implementing authentication can be a difficult thing and a lot of times it is. But thankfully, authentication is built into Lumen, so that all we need to do is enable authentication and then write a few lines of code to authenticate a user and then a few more lines of code to protect the things that we want to protect. Now in our example, we want to protect three methods on our guitar controller. They are the create, the update, and delete methods. These are things that only an authenticated user should have access to. So let's start by going to the bootstrap folder and opening up app.php. There are two statements that we need to uncomment. The first is where a call to routeMiddleware, and this is setting up the authentication middleware. So we want to uncomment that and we also want to register the auth service provider. So the second statement is that one as well and just by uncommenting those two statements we can now use authentication in our application. Now we want to make note of our authentication middleware. This is an app HTTP middleware and authenticate. So let's go there, and inside of this class there is a method called handle and this method will execute before our protected methods. So any time that we make a request for our create, update or delete methods, the authentication middleware is going to be used and this handle method is going to be called. If the user is not authenticated, then it will return a 401. Otherwise, it will pass the request onto the next thing that will process that request. So that is one thing that we needed to look at. The other is inside of the provider's folder. And there is the auth service provider. Now at the bottom of this file is a method called boot and inside of boot is a call to this via request method. And this is the method that is responsible for actually authenticating the user. So this is going to be dependent upon our implementation. And in this lesson, our implementation is going to be very, very, very, simple. What we are going to do is check for a header called Api-token. And if it's a certain value then we are going to say that the user is authenticated. In order to say that a user is authenticated, we have to return a user instance. If we return null, then that means that the user is not authenticated. So let's go ahead and write that code. I'm going to comment out this existing code. And the first thing we're going to do is retrieve the Api-token header. So we're going to use our request, we're going to call the header method and we want Api-token. Now, let me first of all say that this is not secure. I mean, we would definitely want to store our users in a database. They should each have their own unique tokens and really we should be working with private and public keys. But I'm going to leave all of the implementation details up to you. What we want to see is how the authentication middleware plugs into our application so we could get that working, and then you can implement whatever it is that you want to implement. So we are going to retrieve the header called Api-token. And let's first of all check to see if we have something there. So if header and if header is equal to some arbitrary value, let's just say foobar or okay, let's just do something a little bit more complex and let's say birds fly south. Then we are going to say that our user is authenticated. So we will return a new user. Otherwise, we will just return null. Now, the only other thing that we need to do is say where we want to use our authentication middleware. We can do that in a variety of places. The first is whenever we define our routes. For example, we want to protect our post request. So instead of writing our route like we did, we could do this. It's essentially the same thing, but the second argument that we passed to the post method is going to have two keys and values. The first is middleware. So, we would say middleware and then the value for that would be off. And then the second key would be uses. And the value would be our controller's method. So without going any further, we could hop on over to Fiddler and we can make a post request and we could see if that would be protected. Now one of the great things about Fiddler is that it keeps track of all of the requests that we have made. So we just need to find where we made a POST request. There it is, and if we try to execute this, we should get a 401. And we do, but if we include that Api-token header, and if we set that to birds fly south, then whenever we make this request we should get a 200, which we do, and we already know that that data is now in the database. So that's the first option. But the second option is to specify our middleware inside of our controller's constructor. So let's do that. I'm going to leave this here in the code but let's just comment that out and let's use our old route. Let's go to our guitar controller. Now we don't have a constructor here but we can easily add one. So public function and then construct. And inside of this constructor, we want to say that we want to use the authentication middleware. So we will say this middleware and then we want to use the auth middleware. But we can't just do this because this is going to end up protecting all of the methods within this controller. Instead we want to specify just the create, update and delete. So we're going to pass something as the second argument. The key is going to be only, and then the value is going to be an array of all the method names that we want to protect. So create, update and delete. So if we go back to Fiddler and if we issue that same request, let's just change the value to a strat and the make to Fender, then we are going to see that it still works. So let's execute that request. We get a 200. If we take out the Api-token, then we are going to get a 401. But now let's also issue some of the other requests. So let's do a put request although now that we have some guitars in there with different IDs, let's make it a GET request so that we can at least retrieve those guitars and get their IDs. Let's get rid of the Api-token just so that we can see that this works without any type of authentication. And here we have ID of 1 and ID of 2. So if we go back to the composer, let's make a PUT request for the guitar and ID of 2. The data that we are going to send, the make is going to be Fender, but let's change the model from a strat to a telecaster. Now without the Api-token this should not work. So whenever we execute, we get a 401. But let's add the Api-token and then the value, birds fly south, or we can try something that isn't, or birds fly south. We can just try that. We see 401 again. But birds fly south, and then that request is just is going to return 200. So just for the sake of completeness, let's do a delete request. Let's delete the guitar with an ID of 1. We're not going to check to see if it doesn't work by removing the Api-token. Let's just execute this. We should get 200, and a let's re-issue the request to retrieve all of our guitars. And we should just have one, and it should have an ID of 2. The make is Fender, the model is telecaster. So adding authentication to a Lumen application is very, very simple. And other than adding the middleware, the bulk of the code that you have to write is inside of the auth service provider class. You have to write the code responsible for authenticating the user, but once that's done. You have a secure API.