Token Auth with Sanctum0:00
We can implement User authentication for our application in a variety of different ways, but the standard is to use tokens, and Laravel Sanctum makes it very easy to use tokens within your application. Now, I don't mean to imply that we are using Sanctum just because it's easy. I mean, yes, that is a very big reason why we are using it, but it's also perfect for our needs because we can easily create tokens for users, we can assign abilities to tokens, which we will look at in a later episode, and that will give us the ability to control what users can and can't do. But also very importantly, it's installed. We don't have to do anything because whenever we created our project, Sanctum was installed.
Create Login Request0:43
But also very importantly, it's installed. We don't have to do anything because whenever we created our project, Sanctum was installed as well. All we really need to do is provide the ability for users to sign in, and then we can create a token for them. So let's start by creating a LoginRequest. So we will use php artisan make:request to make a request. We'll call it Api\LoginUserRequest. And let's go ahead and write the validation rules for that request. Now, since I prefixed it with Api, it is automatically in the API namespace as well.
And let's go ahead and write the validation rules for that request. Now, since I prefixed it with API, it is automatically in the API namespace as well as the API folder. So we're good to go as far as our structure is concerned. Let's change the authorize to return true because if it's false, users won't be able to sign in at all. And then for our validation rules, we will have an email. So we want to make sure that it is required and that it is a string. We can also say that it is a valid email address. And then we also need to validate the password, which is almost the same.
Move API AuthController1:50
We can also say that it is a valid email address. And then we also need to validate the password, which is almost the same. It needs to be required and a string, but let's say that it needs to have a minimum characters of eight. And that's going to be good enough, I think, for us. So with that done, we need to go to our AuthController. Now, our AuthController we created before we started designing our API. So I want to move the AuthController into the API folder because the authentication for our API would be different from our normal web application. So inside of here then, we need to make a few changes.
the authentication for our API would be different from our normal web application. So inside of here then, we need to make a few changes. The namespace is now API. We need to use app\Http\Controllers and then Controller. And we also need to update that inside of our route file. So let's go to api.php and we just need to add the API to the namespace and that should fix that. So now for our login method, we want to accept the loginUserRequest. And the first thing we need to do is validate that data. So we will use request()->validated() and
And the first thing we need to do is validate that data. So we will use request()->validate() and we want to validate all of the request data. And if we have valid data, then we want to attempt to authenticate the User. So we will call the attempt method and then we will pass in only the email and the password. Now, if this fails, we need to tell the client that authentication failed. So we have our traits for our API responses, but currently we only have successful responses. Let's have an error response.
Return Token in Response3:46
but currently we only have successful responses. Let's have an error response. Let's copy the success and change the name to error. And really, except for having a default value for statusCode, I think that that is going to be just fine. We still have the message, the status, and everything is good there. So when the authentication fails, then we will call our error. And we'll just say invalidCredentials. And then for the HTTP status code, we'll say 401 for unauthorized. But if authentication is successful,
And then for the HTTP status code, we'll say 401 for unauthorized. But if authentication is successful, then we need to fetch the User from the database. So let's call first where the email is the same as the email provided in the request, and then we will return an okay response. But we also need to include the token here. So we're going to need to change our API response just a little bit so that we can have the message. But then let's also say that we will pass data in as well, which means we will need to modify the success method, which should be fine.
But then let's also say that we will pass data in as well, which means we will need to modify the success method, which should be fine. We'll just add the data, and that will be simply data. So that should be fine. Let's go back to our AuthController. So the message will simply say authenticated, and then we will have our data. Our data will have a token key, and this is where we will have the User object to create our token. Now we need to supply a name for our token, and the name is really arbitrary.
this is where we will have the User object to create our token. Now we need to supply a name for our token, and the name is really arbitrary. And this would be something that the User would assign if we had a profile page and they created a token, they could give it their own name. They don't really have that capability here. We might could add that in with the login request, but I don't see a need to do that. So it really doesn't matter what this name is. So we'll just say API token 4, and then we will concatenate the user's email address.
Test Login in Postman5:57
So we'll just say API token four, and then we will concatenate the user's email address. And then from here, this is going to return a hashed value. So we want the plain text token. So we should be able to make this request, get the token that we will then use for all of our other requests. And that's how we will authenticate the user for every request. So let's go to Postman, and let's go to the login request. And we need to change some of these, although we need an actual User. So let's go to the database, and let's just pick one of these.
And we need to change some of these, although we need an actual User. So let's go to the database, and let's just pick one of these. This first one looks kind of easy, this jcoss@example.com. So let's sign in as them, and the password is simply password. Let's check our headers, make sure that we are sending the Accept header we are. So let's send this, we should get a response back, and there it is. We have our data, we have our token. So this value right here is important. We are sending this to the User, and this is the token that they are going to include with every request going forward.
Protect Routes with Sanctum7:04
We are sending this to the user, and this is the token that they are going to include with every request going forward. This is how we will authenticate the incoming requests. So if a request doesn't have this token, then they won't be able to access whatever it is that we want to protect. So let's look at how we can protect a route. So let's go to our v1 routes. And let's just say that for right now, we're going to be sure that only authenticated users can access the tickets endpoint. So we can easily do that by calling route middleware.
only authenticated users can access the tickets endpoint. So we can easily do that by calling route middleware. We will specify the auth:sanctum middleware, and then we will call API resource. So this is going to ensure that in order to access our tickets resources, the request has to include a sanctum token. So how do we do that then? Well, let's go to our tickets request. Let's go to our headers, and let's add the Accept header. The value will be application/json.
Let's go to our headers, and let's add the Accept header. The value will be application/json. Let's go ahead and let's just send that request. We will get a response back saying unauthenticated. But to show that we are authenticated, let's go to Authorization here. And we are going to set the type to a Bearer token. We will paste in the token value that we got whenever we signed in. Let's go ahead and save this. And whenever we send this request now, we will see that we get the response that we were hoping for.
And whenever we send this request now, we will see that we get the response that we were hoping for. We get all of our tickets. So the only time that the User will need to provide their email address and their password is whenever they sign in, hitting the login endpoint. They will get that token that the client will then need to include as a bearer token for every request. That sounds cumbersome, but that's just how it is. That's a whole lot easier than having to send email and password for every request going forward.
That's a whole lot easier than having to send email and password for every request going forward. In the next episode, we will look at how to revoke those tokens.
