A simple way of authenticating your APIs with API keys using Laravel. This package uses the following libraries:
- philsturgeon's Fractal
- maximebeaudoin's api-response
The concept for managing API keys is also taken from Phil Sturgeon's codeigniter-restserver. I've been looking for an equivalent for Laravel but did not find any so this is an implementation for that.
**Laravel 5.1.x to 5.3.x: ~3.*
**Laravel 5.1.x: ~2.*
**Laravel 4.2.x: ~1.*
(Recently updated version for Laravel 4. Please note that there are namespace changes here)
**Laravel 4.2.x: 0.*
(The version that most of you are using)
Run composer require petyots/api-guard
In your config/app.php
add Chrisbjr\ApiGuard\Providers\ApiGuardServiceProvider
to the end of the providers
array
'providers' => array(
...
Chrisbjr\ApiGuard\Providers\ApiGuardServiceProvider::class,
),
Add the ApiGuardAuth
facade to the end of the aliases
array as well
'aliases' => array(
...
'ApiGuardAuth' => \Chrisbjr\ApiGuard\Facades\ApiGuardAuth::class,
),
Add the following middleware inside your app/Http/Kernel.php
file:
protected $routeMiddleware = [
...
'apiguard' => \Chrisbjr\ApiGuard\Http\Middleware\ApiGuard::class,
];
Now publish the migration and configuration files for api-guard:
$ php artisan vendor:publish --provider="Chrisbjr\ApiGuard\Providers\ApiGuardServiceProvider"
Then run the migration:
$ php artisan migrate
It will setup two tables - api_keys and api_logs.
Note: Documentation for use with Laravel 5.0.x and 5.1.x differs from Laravel 5.2.x. Please refer to the README here.
Note: Documentation for use with Laravel 4.2.x differs from Laravel 5.0.x. Please refer to the README here. If you are using version 0.*
you can find the README here
Once you're done with the required setup, you can now generate your first API key.
Run the following command to generate an API key:
php artisan api-key:generate
Generally, you will want to generate API keys for each user in your application. The api_keys
table has a user_id
field which you can populate for your users.
To generate an API key that is linked to a user, you can do the following:
php artisan api-key:generate --user-id=1
To generate an API key from within your application, you can use the following method in the ApiKey
model:
$apiKey = Chrisbjr\ApiGuard\Models\ApiKey::make()
Basic usage of ApiGuard is to create a controller and extend that class to use the ApiGuardController
.
Note: The namespace of the ApiGuardController
differs from previous versions.
<?php
use Chrisbjr\ApiGuard\Http\Controllers\ApiGuardController;
class BooksController extends ApiGuardController
{
public function all()
{
$books = Book::all();
return $this->response->withCollection($books, new BookTransformer);
}
public function show($id)
{
try {
$book = Book::findOrFail($id);
return $this->response->withItem($book, new BookTransformer);
} catch (ModelNotFoundException $e) {
return $this->response->errorNotFound();
}
}
}
You should be able to use the api-response object by using $this->response
. More examples can be found on the Github page: https://github.com/ellipsesynergie/api-response.
You can access the above controller by creating a basic route in your app/routes.php
:
Route::get('api/v1/books', 'BooksController@all');
Route::get('api/v1/books/{id}', 'BooksController@show');
You will need to use your API key and put it in the header to access it. By default, the header value is using the X-Authorization
parameter. You can change this in the config file.
Try calling this route using curl
curl --header "X-Authorization: 2ed9d72e5596800bf805ca1c735e446df72019ef" http://localhost:8000/api/v1/books
You should get the following response:
{
"data": {
"id": 1,
"title": "The Great Adventures of Chris",
"created_at": {
"date": "2014-03-25 18:54:18",
"timezone_type": 3,
"timezone": "UTC"
},
"updated_at": {
"date": "2014-03-25 18:54:18",
"timezone_type": 3,
"timezone": "UTC"
},
"deleted_at": null
}
}
There are various options that can be specified for each method in your controller. These options can be specified inside the $apiMethods
variable. Examples can be found below.
By default, all the methods in the ApiGuardController will be authenticated. To turn this off for a specific method, use the keyAuthentication
option.
<?php
use Chrisbjr\ApiGuard\Http\Controllers\ApiGuardController;
class BooksController extends ApiGuardController
{
protected $apiMethods = [
'show' => [
'keyAuthentication' => false
],
];
...
}
This above example will turn off key authentication for the show
method.
If you take a look at the api_keys
table in your database, you will notice that there is a level
field.
This will allow you to specify a level for your API key and if the method has a higher level than the API key, access will be restricted. Here is an example on how to set the level on a method:
<?php
use Chrisbjr\ApiGuard\Http\Controllers\ApiGuardController;
class BooksController extends ApiGuardController
{
protected $apiMethods = [
'show' => [
'level' => 10
],
];
...
}
Now if your API key has a level of 9 or lower, then access to the show
method will be restricted.
You can limit the rate at which an API key can have access to a particular method by using the limits.key
option.
<?php
use Chrisbjr\ApiGuard\Http\Controllers\ApiGuardController;
class BooksController extends ApiGuardController
{
protected $apiMethods = [
'show' => [
'limits' => [
'key' => [
'increment' => '1 hour',
'limit' => 100
]
]
],
];
...
}
The above example will limit the access to the show
method of an API key to 100 requests for every hour.
Note: The increment
option can be any value that is accepted by the strtotime()
method.
There is also an option to limit the request rate for a given method no matter what API key is used. For this, we use the limits.method
option.
<?php
use Chrisbjr\ApiGuard\Http\Controllers\ApiGuardController;
class BooksController extends ApiGuardController
{
protected $apiMethods = [
'show' => [
'limits' => [
'method' => [
'increment' => '1 day',
'limit' => 1000
]
]
],
];
...
}
The above example will limit the request rate to the show
method to 1000 requests per day.
Note: The increment
option can be any value that is accepted by the strtotime()
method.
You can set logging at method level by using the logged
option.
<?php
use Chrisbjr\ApiGuard\Http\Controllers\ApiGuardController;
class BooksController extends ApiGuardController
{
protected $apiMethods = [
'show' => [
'logged' => true
]
];
...
}
By default for all methods in api-guard, the option logged
is set to true. Set it to false
to exclude that method for logging.