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 the role of bridge to passing data between mobile applications and the web. Keeping APIs call safe and authenticated is important to protect the data being transferred from application to application.

In this article, we study 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 interaction with the application. Laravel Passport provides a convenient way to create and verify tokens against the API call.

Installation

For getting started, we assume you have installed 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 an 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 its own database migrations directory. These migrations will create tables that store the clients and access tokens.

In your config/app.php file, register the 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. The below command creates “personal access” and “password grant” clients which are getting stored in the table oauth_clients.

php artisan passport:install
Passport Install

The user can copy these tokens for the 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 an Authorization token we get an ‘Unauthenticated’ response.

Unauthenticated

It means while calling API it is essential to pass the 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 the first option, you have to give a call to the /oauth/token with the required parameters and you will get the token in response.

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

<?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);

The above code returns an array that 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

Actually you need to call this API like the 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 the 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 tokens through login credentials only.

In our ApiController.php add the login method with the 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');

Users can make HTTP post requests 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 *