A simple way of authenticating your RESTful APIs with API keys using Laravel

Related tags

API api-guard
Overview

ApiGuard

This package is no longer maintained

This package is no longer maintained as Laravel already has a similar feature built-in since Laravel 5.8 and Laravel 6.x. Documentation on Laravel's API authentication can be found here. Furthermore, since Laravel 7.x, there is a new Laravel package called Airlock/Sanctum that would better serve API authentication purposes.

Latest Stable Version Total Downloads

Join the chat at https://gitter.im/chrisbjr/api-guard

A simple way of authenticating your APIs with API keys using Laravel. This package uses the following libraries:

Laravel 5.3, 5.4 and 5.5 is finally supported!

**Laravel 5.3.x onwards: ~4.*

**Laravel 5.1.x to 5.2.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)

Quick start

Installation for Laravel 5.3 to 5.4

Run composer require chrisbjr/api-guard 4.*

In your config/app.php add Chrisbjr\ApiGuard\Providers\ApiGuardServiceProvider to the end of the providers array

'providers' => array(

    ...
    Chrisbjr\ApiGuard\Providers\ApiGuardServiceProvider::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 api_keys table.

Generating your first API key

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, the ApiKey object is a polymorphic object meaning this can belong to more than one other model.

To generate an API key that is linked to another object (a "user", for example), you can do the following:

+php artisan api-key:generate --id=1 --type="App\User"

To specify that a model can have API keys, you can attach the Apikeyable trait to the model:

use Chrisbjr\ApiGuard\Models\Mixins\Apikeyable;

class User extends Model
{
    use Apikeyable;

    ...
}

This will attach the following methods to the model:

// Get the API keys of the object
$user->apiKeys();

// Create an API key for the object
$user->createApiKey();

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()

// Attach a model to the API key
$apiKey = Chrisbjr\ApiGuard\Models\ApiKey::make($model)

Usage

You can start using ApiGuard by simply attaching the auth.apikey middleware to your API route:

Route::middleware(['auth.apikey'])->get('/test', function (Request $request) {
    return $request->user(); // Returns the associated model to the API key
});

This effectively secures your API with an API key which needs to specified in the X-Authorization header. This can be configured in config/apiguard.php.

Here is a sample cURL command to demonstrate:

curl -X GET \
  http://apiguard.dev/api/test \
  -H 'x-authorization: api-key-here'

You might also want to attach this middleware to your api middleware group in your app/Http/Kernel.php to take advantage of other Laravel features such as throttling.

/**
 * The application's route middleware groups.
 *
 * @var array
 */
protected $middlewareGroups = [
    ...

    'api' => [
        'throttle:60,1',
        'bindings',
        'auth.apikey',
    ],
];

If you noticed in the basic example, you can also access the attached model to the API key by calling $request->user(). We are attaching the related model in this method because in most use cases, this is actually the user.

Unauthorized Requests

Unauthorized requests will get a 401 status response with the following JSON:

{
  "error": {
    "code": "401",
    "http_code": "GEN-UNAUTHORIZED",
    "message": "Unauthorized."
  }
}

ApiGuardController

The ApiGuardController takes advantage of Fractal and api-response libraries.

This enables us to easily create APIs with models and use transformers to give a standardized JSON response.

Here is an example:

Let's say you have the following model:

use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    protected $fillable = [
        'name',
    ];
}

You can make a basic controller which will return all books like this:

use Chrisbjr\ApiGuard\Http\Controllers\ApiGuardController;
use App\Transformers\BookTransformer;
use App\Book;

class BooksController extends ApiGuardController
{
    public function all()
    {
        $books = Book::all();

        return $this->response->withCollection($books, new BookTransformer);
    }
}

Now, you'll need to make the transformer for your Book object. Transformers help with defining and manipulating the variables you want to return to your JSON response.

use League\Fractal\TransformerAbstract;
use App\Book;

class BookTransformer extends TransformerAbstract
{
    public function transform(Book $book)
    {
        return [
            'id'         => $book->id,
            'name'       => $book->name,
            'created_at' => $book->created_at,
            'updated_at' => $book->updated_at,
        ];
    }
}

Once you have this accessible in your routes, you will get the following response from the controller:

{
  "data": {
    "id": 1,
    "title": "The Great Adventures of Chris",
    "created_at": {
      "date": "2017-05-25 18:54:18",
      "timezone_type": 3,
      "timezone": "UTC"
    },
    "updated_at": {
      "date": "2017-05-25 18:54:18",
      "timezone_type": 3,
      "timezone": "UTC"
    }
  }
}

More examples can be found on the Github page: https://github.com/ellipsesynergie/api-response.

To learn more about transformers, visit the PHP League's documentation on Fractal: Fractal

API Validation Responses

ApiGuard comes with a request class that can handle validation of requests for you and throw a standard response.

You can create a Request class as you usually do but in order to get a standard JSON response you'll have to extend the ApiGuardFormRequest class.

use Chrisbjr\ApiGuard\Http\Requests\ApiGuardFormRequest;

class BookStoreRequest extends ApiGuardFormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'name' => 'required',
        ];
    }
}

Now you can use this in your controller as you normally do with Laravel:

use Chrisbjr\ApiGuard\Http\Controllers\ApiGuardController;
use App\Transformers\BookTransformer;
use App\Book;

class BooksController extends ApiGuardController
{
    public function store(BookStoreRequest $request)
    {
        // Request should already be validated

        $book = Book::create($request->all())

        return $this->response->withItem($book, new BookTransformer);
    }
}

If the request failed to pass the validation rules, it will return with a response like the following:

{
  "error": {
    "code": "GEN-UNPROCESSABLE",
    "http_code": 422,
    "message": {
      "name": [
        "The name field is required."
      ]
    }
  }
}
Comments
  • Lumen compatibility

    Lumen compatibility

    I wanted to see if API Guard was Lumen was compatible, and whilst it isn't yet, I think there's a few small tweaks could enable it. I suspect a lot of it is down to class aliases (as they're not included in Lumen) and some dependancies.

    The first step you have to do is uncomment $app->withFacades(); on line 20 in app.php.

    Then the issues are happening when trying to using artisan to publish the migration and configurations:

    Fatal error: Class 'Response' not found in /lumen/vendor/ellipsesynergie/api-response/src/Laravel/ResponseServiceProvider.php on line 29
    

    Line 29 is:

     \Response::macro('api', function () {
    

    I would expect that references Laravel's standard Response facade which is fixed with:

    \Illuminate\Support\Facades\Response::macro('api', function () { 
    

    That appeared to fix it that - but it moved onto another issue when running artisan:

      [Illuminate\Container\BindingResolutionException]
      Target [Illuminate\Contracts\Routing\ResponseFactory] is not instantiable.
    

    I've yet to resolve what the problem is with this - does anyone else have any ideas?

    enhancement 
    opened by jayhealey 12
  • Getting error in fresh installation BooksController

    Getting error in fresh installation BooksController

    Hello thanks in advance i am using this package and it realy suit my project what i am building...after updating i am getting these error on all request

    ErrorException in ApiGuardAuth.php line 14: Argument 1 passed to Chrisbjr\ApiGuard\ApiGuardAuth::__construct() must be an instance of Chrisbjr\ApiGuard\Contracts\Providers\Auth, null given, called in E:\xammp\htdocs\vox\didww\vendor\chrisbjr\api-guard\src\Providers\ApiGuardServiceProvider.php on line 49 and defined

    any suggestion?

    opened by adnanmayo 8
  • Testing Guarded controllers

    Testing Guarded controllers

    Hi, I've been working on a project and am implementing functional unit tests with phpunit on laravel 4.2, and I was wondering if you have any hints as to how to get apiguard bootstrapped with the testing framework so I can test against a controller's methods.. Any help would be appreciated!

    Thanks, Geoff

    opened by goslund 8
  • Unauthorized access on show method

    Unauthorized access on show method

    When accessing my API via http://url.dev/api/v1/events I am returned with all events as you would expect. This works with and without the API key when using the

    'keyAuthentication' => false,

    However if I try to return just one record with http://url.dev/api/v1/events/3 I get the following even when using the key is switched off:

    ``{"error":{"code":"GEN-UNAUTHORIZED","http_code":401,"message":"Unauthorized"}}`

    My show method -

    public function show($id)
    {
        $event = Ev::find($id);
        if(!$event){
            return Response::api()->errorNotFound('Event Not Found');
        }
        return $this->response->withItem($event, new EventTransformer);
    }
    

    Any help is appreciated. :)

    Steven

    opened by richdynamix 8
  • Installation error with Laravel 5.3

    Installation error with Laravel 5.3

    Hello,

    composer require chrisbjr/api-guard 3.1.*
    
    Problem 1
        - Conclusion: remove laravel/framework v5.3.16
        - Conclusion: don't install laravel/framework v5.3.16
        - chrisbjr/api-guard v3.1.0 requires illuminate/auth 5.1.* || 5.2.* -> satisfiable by illuminate/auth[v5.1.1, v5.1.13, v5.1.16, v5.1.2, v5.1.20, v5.1.22, v5.1.25, v5.1.28, v5.1.30, v5.1.31, v5.1.41, v5.1.6, v5.1.8, v5.2.0, v5.2.19, v5.2.21, v5.2.24, v5.2.25, v5.2.26, v5.2.27, v5.2.28, v5.2.31, v5.2.32, v5.2.37, v5.2.43, v5.2.45, v5.2.6, v5.2.7].
        - chrisbjr/api-guard v3.1.1 requires illuminate/auth 5.1.* || 5.2.* -> satisfiable by illuminate/auth[v5.1.1, v5.1.13, v5.1.16, v5.1.2, v5.1.20, v5.1.22, v5.1.25, v5.1.28, v5.1.30, v5.1.31, v5.1.41, v5.1.6, v5.1.8, v5.2.0, v5.2.19, v5.2.21, v5.2.24, v5.2.25, v5.2.26, v5.2.27, v5.2.28, v5.2.31, v5.2.32, v5.2.37, v5.2.43, v5.2.45, v5.2.6, v5.2.7].
        - don't install illuminate/auth v5.1.1|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.1.13|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.1.16|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.1.2|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.1.20|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.1.22|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.1.25|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.1.28|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.1.30|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.1.31|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.1.41|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.1.6|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.1.8|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.2.0|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.2.19|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.2.21|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.2.24|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.2.25|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.2.26|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.2.27|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.2.28|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.2.31|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.2.32|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.2.37|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.2.43|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.2.45|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.2.6|don't install laravel/framework v5.3.16
        - don't install illuminate/auth v5.2.7|don't install laravel/framework v5.3.16
        - Installation request for laravel/framework == 5.3.16.0 -> satisfiable by laravel/framework[v5.3.16].
        - Installation request for chrisbjr/api-guard 3.1.* -> satisfiable by chrisbjr/api-guard[v3.1.0, v3.1.1].
    

    Bests

    opened by sylouuu 7
  • Allow empty serializedApiMethods and Authenticate User with api-guard middleware

    Allow empty serializedApiMethods and Authenticate User with api-guard middleware

    I just was notified of the acceptation of @gholol pull request ( https://github.com/chrisbjr/api-guard/pull/85 ) about api-guard as a laravel middleware. These are the changes I made from his code.

    Basically it just let the possibility to send no "options" and it authenticate the current user so it becomes accessible via Auth::user()

    The last thing I would might change on this, is : Adding the possibility to send "$serializedApiMethods" as plain php Array and not as serialized array, let me know if you interrested and I'll commit modifications

    You did there great work, hope you'll accept this request

    opened by rchoffardet 7
  • apache_request_headers() undefined

    apache_request_headers() undefined

    When I extend ApiGuardController in my controller I get this error.

    FatalThrowableError in ApiGuard.php line 195: Fatal error: Call to undefined function Chrisbjr\ApiGuard\Http\Middleware\apache_request_headers()

    Not all PHP configs support apache_request_headers. Are you planning fix it?

    PHP docs

    opened by maksymkhar 6
  • Predefined route for generating new token

    Predefined route for generating new token

    I think the url for getting a new token should be http://localhost:8000/apiguard/generate(according to the source code) instead of $ curl -X POST http://localhost:8000/apiguard/api_key as the document says.

    opened by tienkhoi 6
  • Not working on Laravel 5.4.21

    Not working on Laravel 5.4.21

    api-guard stopped working on newer versions of Laravel 5.4. I have not changed anything in my code regarding api-guard, controllers, settings etc. It looks like it is never called... Is there any known issue which prevents use of api-guard?

    opened by JanRajtr 5
  • Class 'ApiGuardAuth' not found

    Class 'ApiGuardAuth' not found

    Hello. Thank you for your work. I tried to use the last commit from the branch and got the error message: FatalErrorException in ApiGuard.php line 99: Class 'ApiGuardAuth' not found

    I changed the code to include the ApiGuardAuth from the main directory of package, but got the next error message: ErrorException in ApiGuard.php line 99: Non-static method Chrisbjr\ApiGuard\ApiGuardAuth::authenticate() should not be called statically, assuming $this from incompatible context

    What should I change? Thank you. Best regards, Andrey Baranov

    opened by robotNIXX 5
  • Method Not Allowed

    Method Not Allowed

    Laravel 5.2 protected $routeMiddleware = [ ... 'apiguard' => \Chrisbjr\ApiGuard\Http\Middleware\ApiGuard::class, ... ];

    I am getting: {"error":{"code":"GEN-METHOD-NOT-ALLOWED","http_code":405,"message":"Method Not Allowed"}} My user was created with --user-id=2

    And my curl request is: curl --header "X-Authorization: 3bbc442956f0092601ab76f788d31bf3c2943bb1" http://localhost:8000/api/v1/tables

    Route::get('api/v1/tables', 'Api\TablesController@all'); and the controller:

    class TablesController extends ApiGuardController
    {
      public function all(Request $request)
        {
            $tables = Tables::all();
    
          return $this->response->withCollection($tables, new TableTransformer);
        }
    
    }
    

    Its pretty much straight from your guide... so what is wrong?

    opened by tpharaoh 5
  • fixed unauthorizedResponse

    fixed unauthorizedResponse

    during the upgrade from 3.* to 4.* the unauthorised response changed from

    [
        'error' => [
            'code' => 'GEN-UNAUTHORIZED',
            'http_code' => 401,
            'message' => 'Unauthorized'
        ]
    ]
    

    to

    [
        'error' => [
            'code' => '401',
            'http_code' => 'GEN-UNAUTHORIZED',
            'message' => 'Unauthorized.'
        ]
    ]
    

    However it makes more sense that 401 is the http_code not code (and also an int) (The upgrade also added a . at the end of the message, which is IMHO a valid change)

    opened by sebzap 0
  • Slow Query

    Slow Query

    I am using api-guard in the normal way. When I look at the query times in the debug toolbar, the api-guard query is always tagged as slow:

    select * fromapi_keyswherekey= '0b0c7be24c74c79c7efe7568b770749f1599cf60' andapi_keys.deleted_atis null limit 1

    Time = 184.12ms

    Why is the query so slow? What can I do to speed it up?

    If I run the query direct on my database then it runs very quickly.

    opened by PaddyLock 3
  • How to fill apikeyable_id in controller file

    How to fill apikeyable_id in controller file

    How to fill apikeyable_id column like this command php artisan api-key:generate --id=1 --type="App\User" in controller file?

    I try

         $user = User::find(10);
         $user->createApiKey();
    

    But the apikeyable_id still null. apikeyable_type . have the good value.

    opened by khoude24 0
  • auth.apikey must be placed before throttling middleware ?

    auth.apikey must be placed before throttling middleware ?

    Half a comment / Half a question

    Laravel: v5.6 api-guard: v4.1

    In the Http/Kernel.php file, middleware section I noticed that

    Is half-working since the user won't be set in the $request object throttling middleware class. $request->user() will always return null.

            'api' => [
                'throttle:rate_limit,1',
                'auth.apikey',
                ...
            ],
    

    The following is working though

            'api' => [
                'auth.apikey',
                'throttle:rate_limit,1',
                ...
            ],
    

    As far as I remember middlewares are prioritized so this may be expected, but the documentation is wrong and should be

    /**
     * The application's route middleware groups.
     *
     * @var array
     */
    protected $middlewareGroups = [
        ...
    
        'api' => [
            'auth.apikey',
            'throttle:60,1',
            'bindings',
        ],
    ];
    

    Correct me if I am wrong, I'll be pleased to assist and give more details on our laravel setup.

    Edited: Just to clarify our use case, we want to accept visitor and limit their rate with a really low threshold. To do so we need to change the middleware to not send a unauthorized response.

    opened by damsvann 0
Releases(v3.1.2)
Owner
Chris Bautista
CTO and co-founder of CoreProc, Inc.
Chris Bautista
PHP SDK for Checkout RESTful APIs

REST API SDK for PHP V2 To consolidate support across various channels, we have currently turned off the feature of GitHub issues. Please visit https:

PayPal 400 Nov 29, 2022
PHP SDK for PayPal RESTful APIs

Deprecation Notice: This SDK is deprecated. You can continue to use it, but no new features or support requests will be accepted. For alternatives, pl

PayPal 2.1k Jan 5, 2023
A simple example of how to create a RESTful API in Laravel Framework 8.36.1.

FirstLaravel A simple example of how to create a RESTful API in Laravel Framework 8.36.1. I used Database sqlite because I wanted to deploy this proje

Max Base 4 Apr 16, 2021
Best resources restful api for developers (with JSON:API standar specification design)

List API Best resources restful api for developers (with JSON:API standar specification design). API Resource Endpoint Name Resource Description Al Qu

Noval 2 Jan 18, 2022
A RESTful API package for the Laravel and Lumen frameworks.

The Dingo API package is meant to provide you, the developer, with a set of tools to help you easily and quickly build your own API. While the goal of

null 9.3k Jan 7, 2023
My first laravel restful api project

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Amirhosein Mohammadian 2 Oct 13, 2021
Fully documented & tested Laravel 9 RESTful books API scraped from Gramedia.

Laravel Books API Introduction This app provides a list of books in a RESTful API. Source of data obtained from Gramedia by using the web scraping tec

Yusuf T. 44 Dec 23, 2022
Zoho CRM API SDK is a wrapper to Zoho CRM APIs. By using this sdk, user can build the application with ease

Archival Notice: This SDK is archived. You can continue to use it, but no new features or support requests will be accepted. For the new version, refe

null 81 Nov 4, 2022
Best resources restful api for developers

Best resources restful api for developers (with JSON:API standar specification design).

Noval 2 Jan 18, 2022
A RESTful and extendable Backend as a Service that provides instant backend to develop sites and apps faster, with dead-simple integration for JavaScript, iOS, Android and more.

Welcome to hook ![Gitter](https://badges.gitter.im/Join Chat.svg) hook is a RESTful, extendable Backend as a Service that provides instant backend to

doubleleft 762 Dec 30, 2022
PHP library/SDK for Crypto APIs 2.0 using Guzzle version 7

cryptoapis/sdk-guzzle7 Crypto APIs 2.0 is a complex and innovative infrastructure layer that radically simplifies the development of any Blockchain an

Crypto APIs 3 Oct 21, 2022
The server component of API Platform: hypermedia and GraphQL APIs in minutes

API Platform Core API Platform Core is an easy to use and powerful system to create hypermedia-driven REST and GraphQL APIs. It is a component of the

API Platform 2.2k Dec 27, 2022
Shopware PHP SDK is a simple SDK implementation of Shopware 6 APIs

Shopware PHP SDK is a simple SDK implementation of Shopware 6 APIs. It helps to access the API in an object-oriented way.

Thuong Le 77 Dec 19, 2022
Pure PHP APIs with PostgreSQL database, with HTML, CSS & JS simple frontend

The root of the project is html/index.html The folder needs to be put in htdocs folder to run correctly // this link should open the main page if the

ZaydSK 3 Jul 22, 2022
The NelmioApiDocBundle bundle allows you to generate a decent documentation for your APIs

NelmioApiDocBundle The NelmioApiDocBundle bundle allows you to generate a decent documentation for your APIs. Migrate from 3.x to 4.0 To migrate from

Nelmio 2.1k Jan 6, 2023
Laravel cryptocurrency trading APIs.

Lypto API Laravel cryptocurrency trading APIs. Installation Requirements Minimum Laravel version 7.0 Use the following command to install: composer re

Md Obydullah 4 Jan 27, 2022
Laravel api tool kit is a set of tools that will help you to build a fast and well-organized API using laravel best practices.

Laravel API tool kit and best API practices Laravel api tool kit is a set of tools that will help you to build a fast and well-organized API using lar

Ahmed Esa 106 Nov 22, 2022
Transporter is a futuristic way to send API requests in PHP

Transporter Transporter is a futuristic way to send API requests in PHP. This is an OOP approach to handle API requests.

Steve McDougall 369 Dec 22, 2022
This is an attempt to re-write the official TRA VFD's API in a developer friendly way.

TRA VFD API Documentation This is an attempt to re-write the official TRA VFD's API in a developer friendly way. The current documentation is written

Alpha Olomi 15 Jan 7, 2022