Skip to content

Instantly share code, notes, and snippets.

@JacobBennett
Last active March 26, 2021 02:47
Show Gist options
  • Save JacobBennett/090369fbab0b31130b51 to your computer and use it in GitHub Desktop.
Save JacobBennett/090369fbab0b31130b51 to your computer and use it in GitHub Desktop.
API Token Authentication in Laravel 5.2 & 5.3

I recently had the need to write a small url shortening application. I am aware that this problem has been solved quite a few times before, but what is being a developer if not reinventing the wheel just for the heck of it? Custom CMS anyone?

Knowing that this was going to be a tiny RESTful API and also knowing that Laravel 5.2 had API rate limiting built in, I was eager to give it a try. Taylor Otwell being Taylor Otwell shipped 5.2 with the rate limiting defaults set up out of the box and I had my application building out short url's in a matter of minutes. The problem for me came when I wanted to start associating those short urls with a user.

Typically my applications have a UI and authentication is done through a simple login page. Obviously for a RESTful API, having a login page isn't ideal. Instead, my hope was to have users append an api_token to the end of their query string and use that to authenticate their request. I was happy to find that 5.2 also ships with a TokenGuard(link) class that allows you to do exactly that, but the documentation on getting it to work was a bit thin, so here you go.

Set up Token based Authenticaton

1. Add an api_token

The first think you need to do is to add an api_token column to your users table. If you are just starting your application you can likely get away with modifying the user migration that ships with Laravel to include your new column.

	// add this to your users_table migration
	$table->string('api_token', 60)->unique();

Note: Be sure to generate and assign an api_token to new users. Something like str_random(60) should be sufficient.

2. Wrap your routes

Second, we need to make sure that any routes that will be using Token Authentication are being protected by the auth:api middleware. Use the following route group as an example of what your routes might look like.

	Route::group(['prefix' => 'api/v1', 'middleware' => 'auth:api'], function () {
    	Route::post('/short', 'UrlMapperController@store');
	});

Note: Typically when protecting routes from unauthenticated users, we use the auth middleware, but by appending :api to the end we are telling Laravel that we want to use the driver for the api guard which is set up in the config/auth.php and is defaulted to token.

At this point, any routes wrapped with your auth:api middleware are only accessible to those that visit the route with a valid api_token in their request.

3. Getting the User

To get the authenticated user for this API request, use the following snippet:

	Auth::guard('api')->user();

Just like when we called the middleware, we have to let Laravel know that we want the api guard instead of the default web guard.

Extras

In the App\Http\Middleware\Authenticate middleware, you might want to change the following lines:

Update: This has been merged into 5.2. Check out the current Authenticate Middleware here

	// Original
	    if ($request->ajax()) {
	        return response('Unauthorized.', 401);
	    } else {
	        return redirect()->guest('login');
	    }
	    
	// Updated
		if ($request->ajax() || $request->wantsJson()) {
	        return response('Unauthorized.', 401);
	    } else {
	        return redirect()->guest('login');
	    }

This will return a 401 status code to unauthorized API requests instead of redirect it to a login page.

Lastly, if you are planning on primarily using the TokenGuard to authenticate requests, change the default guard in config/auth.php to be api instead of web. That should prevent you from having to tell Laravel to use the api version of the middleware or guard since Laravel will use by default what you have set in config/auth.php.

Wrapping Up

Well there you have it, authenticating users to your api using nothing more than an api_token in the request and an api_token column on your user table. Hopefully this will save you the time it took me digging through the TokenGuard and Issues to figure it out.

published: true
preview: I was happy to find that Laravel 5.2 & 5.3 ships with a TokenGuard class that allows users to authenticate by sending an api_token along with their request, but the documentation on getting it to work is a bit thin, so here you go.
@azazqadir
Copy link

Since this REST API is based on older version of Laravel, I think there is a need to mention how devs can create a REST API on latest version of Laravel, which is currently 5.5 and use a new package for Authentication. We now have Laravel Passport that can be used for easy and quick Laravel REST API authentication (https://www.cloudways.com/blog/rest-api-laravel-passport-authentication/ ). This package provides a full OAuth2 server implementation.

@azazqadir
Copy link

Since this REST API is based on older version of Laravel, I think there is a need to mention how devs can create a REST API on latest version of Laravel, which is currently 5.5 and use a new package for Authentication. We now have Laravel Passport that can be used for easy and quick Laravel REST API authentication (https://www.cloudways.com/blog/rest-api-laravel-passport-authentication/ ). This package provides a full OAuth2 server implementation.

@Milanchhatralia
Copy link

How can we authorize user using Auth::guard('api')->user(); ...
I mean how to check email and password??
Or if it is Using token than how to compare the tokens??

@hosembafer
Copy link

How can I pass email and password of user and get api_token?

@hosembafer
Copy link

How I can pass email and password of user to get api_token?
Do I need write my own route for that?

@azazqadir
Copy link

It is better to use Laravel passport for this. Laravel passport automatically generates api token in Laravel. You just have to install and configure it with your application.

@azazqadir
Copy link

It is better to use Laravel passport for this. Laravel passport automatically generates api token in Laravel. You just have to install and configure it with your application.

@kotofenum
Copy link

Sir, you are my hero for today. I've been so confused with Laravel's passport, but what you explained here is exactly what I was looking for a several days.
Thank you!

@alfredomtzrmz
Copy link

but how do you generate the token and "log in"? i mean how you validate the user credentials and then return the token?

@alfredomtzrmz
Copy link

but how you generate the token and "log in"? i mean how you validate the user credentials

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment