How to Use Laravel Passport for REST API Authentication

In today’s web development, APIs or web services are very popular. While developing a mobile application, API plays a role of bridge to passing data between mobile application and web. Keeping APIs call safe and authenticated is important to protect the data being transferred between application to application.

In this article, we study about Laravel Passport which allows us to authenticate APIs. Passport is built on the top of the OAuth2 server which is much more secure in the way it builds.

When dealing with the APIs, we used to send an access token to verify if the incoming request is valid. If it is authorized then only it should allow interacting with the application. Laravel passport provides a convenient way to create and verify token against the API call.

Installation

For getting started, we assume you have installed the Laravel on your system. To install the Passport, run the below command in the terminal.

composer require laravel/passport

Above command would work with the latest version of Laravel. If you are running older version then the command will be slightly different depending on your Laravel version. For instance, if have Laravel 5.5 installed then your command should be:

composer require laravel/passport=~4.0

This command creates their own database migrations directory. These migrations will create tables which store the clients and access tokens.

In your config/app.php file, register Passport service provider in the providers array.

config/app.php

'providers' =>[
  ....
  Laravel\Passport\PassportServiceProvider::class,
],

Let’s run the migration which will create the database tables for Passport.

php artisan migrate

Now, if you go to your database client, you will notice the new tables created in your database.

Passport Tables

Next, run the below command which creates encryption keys to generate secure access tokens. Below command creates “personal access” and “password grant” clients which are getting store in the table oauth_clients.

php artisan passport:install

Passport Install

The user can copy these tokens for next steps. Actually, we are going to see 2 ways of creating access tokens. One is through this “password grant” clients and another is on login authentication.

Passport Configuration

Head over to the Laravel directories and open App\User model file. In this file we need to add Laravel\Passport\HasApiTokens trait.

app/User.php.

<?php

namespace App;

use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
    ....
}

After this, we have to call Passport::routes method in the boot method of AuthServiceProvider.

app/Providers/AuthServiceProvider.php

<?php

namespace App\Providers;

use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        Passport::routes();
    }
}

At last, in the config/auth.php file set the ‘driver’ option of ‘api’ authentication guard to ‘passport’ as follows:

config/auth.php

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

Create REST API and Protect it with Laravel Passport

Laravel creates a file routes/api.php where we should declare our REST APIs endpoint. We can protect our API by adding the middleware auth:api to it.

routes/api.php

Route::get('/api/categories', 'ApiController@categories')->middleware('auth:api');

For multiple endpoints we don’t need to add middleware each time. Instead, we can do it as follows:

Route::group(['middleware' => 'auth:api'], function(){
    Route::get('products', 'ApiController@products');
    Route::get('categories', 'ApiController@categories');
});

As our endpoint ‘products’ is protected if we call it directly without Authorization token we get an ‘Unauthenticated’ response.

Unauthenticated

It means while calling API it is essential to pass Authorization token in each request. So, Passport will verify the token and returns the response.

Generate Access Token for API

There are several ways to create an access token for the application. We will see 2 of them for this tutorial.

First Option

In a first way, you have to give a call to the /oauth/token with required parameters and you will get the token in response.

We assume you are using a Guzzle HTTP library for making API request. Let’s say you have another project from where you are making API request.

<?php
require_once "vendor/autoload.php";

use GuzzleHttp\Client;

$client = new Client([
    // Base URI is used with relative requests
    'base_uri' => 'http://laravel.dev',
]);

$response = $client->post('/oauth/token', [
    'form_params' => [
        'grant_type' => 'password',
        'client_id' => '2',
        'client_secret' => '8qyKG7WKb3O3FZh2hUyEOZ3dAj5l9S5ljn2bdeJf',
        'username' => 'sajid@test.com',
        'password' => 'my_password',
        'scope' => '*',
    ],
]);

$arr_result = json_decode((string) $response->getBody(), true);

Above code returns an array which contains a key ‘access_token’. The parameters client_id and client_secret we got when we run passport:install. You can also get these details from your database table ‘oauth_clients’.

Again try from postman by passing the access_token to the ‘products’ endpoint and we should get the response.

postman access token

In actual you need to call this API like below:

$response = $client->get('/products', [
    'headers' => [
        'Authorization' => 'Bearer '.$access_token,
    ]
]);

$arr_result = json_decode((string) $response->getBody(), true);

Second Option

In the first option, you should know client_id and client_secret to generate your token. This may be not a convenient way in some scenarios. Passport provides another option to generate access token is through login credentials only.

In our ApiController.php add the login method with post request and write the below code in it.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Auth;

class ApiController extends Controller
{
    public function login(){ 
        if(Auth::attempt(['email' => request('email'), 'password' => request('password')])){ 
            $user = Auth::user(); 
            $success['token'] =  $user->createToken('MyApp')-> accessToken; 
            return response()->json(['success' => $success], 200); 
        } 
        else{ 
            return response()->json(['error'=>'Unauthorised'], 401); 
        } 
    }

For making this API call, we need to register a route for it.

routes/api.php

Route::post('login', 'ApiController@login');

User can make HTTP post request to this API by writing the code below:

$response = $client->post('/api/login', [
    'form_params' => [
        'email' => 'sajid@test.com',
        'password' => 'my_password'
    ],
]);

$arr_result = json_decode((string) $response->getBody(), true);

postman post request

We hope you understand the use of Laravel Passport for REST API Authentication. We would like to hear your thoughts in the comment section below. We also recommend going through the article Laravel API Tutorial: How to Build and Test a RESTful API which we found useful for readers.

If you liked this article, then please subscribe to our YouTube Channel for video tutorials.

7 thoughts on “How to Use Laravel Passport for REST API Authentication

  1. Thank you very much is very helpful, however I hope you can tell me how you could add the verification by mail using passport

  2. User can make HTTP post request to this API by writing the code below:

    $response = $client->post(‘/api/login’, [
    ‘form_params’ => [
    ’email’ => ‘sajid@test.com’,
    ‘password’ => ‘my_password’
    ],
    ]);

    $arr_result = json_decode((string) $response->getBody(), true);

    Where is this code supposed to go?

    1. In the first option, we need to know client id and clint secret while in the second option we just need to pass our email and password.

Leave a Reply

Your email address will not be published. Required fields are marked *