API Authentication with Laravel Janitor: Part 1 — Laravel Passport Proxy

Introduction

On a daily basis I work on several API projects that all have one thing in common: Authentication. To maintain that across the projects, I created a package, Janitor, that allows you to add an authentication proxy to your Laravel application. Out of the box, it provides the following features:

  • Login
  • Reset Password

In this two part series I’ll introduce you to signifly/laravel-janitor and teach you how to set it up withlaravel/passport and tymon/jwt-auth.

NOTE: If you want to skip reading the article and jump right into the code. You’ll find a link to the demo repo here.

Install Passport

To get started, use the Composer package manager to install the package:

composer require laravel/passport

Run the migrate command to create the required tables:

php artisan migrate

Next, we’ll run the passport:install command in order to create the encryption keys used by Passport to generate tokens.

php artisan passport:install

After running the command, we’ll add the Laravel\Passport\HasApiTokens trait to our App\User model.

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

Next, we’ll call the Passport::routes method within the boot method of the AuthServiceProvider.

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

Finally, we’ll modify the driver option of the api guard to passport in our config/app.php file.

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

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

'hash' => false,
],
],

That’s it. Now Passport has been set up. If you want to modify token life-time, please refer to their documentation: https://laravel.com/docs/5.8/passport

Install Janitor

Just like with Passport, we’ll install Janitor using Composer:

composer require signifly/laravel-janitor

Next, let’s publish the config file using thevendor:publish command:

php artisan vendor:publish --tag="janitor-config"

After publishing the config file, we’ll call the Janitor::routes method within our routes/api.php file to add the authentication endpoints from the Proxy.

<?php
use Illuminate\Http\Request;
use Signifly\Janitor\Facades\Janitor;
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Janitor::routes();

Finally, we have to add a few environment variables:

JANITOR_DRIVER=passport
JANITOR_OAUTH_TOKEN_URL=http://localhost/oauth/token

The JANITOR_DRIVER variables has to be set to passport as it is the driver we are using. However, the JANITOR_OAUTH_TOKEN_URL should be customised to match the url of your application. When using Passport with no configuration, it should be a matter of updating the domain name. That means if you use Laravel Valet, then update it accordingly:

JANITOR_OAUTH_TOKEN_URL=http://{project_name}.{valet-domain}/oauth/token

Cool! Now it should be set up correctly. Let’s test it out.

Test endpoints with Postman

Before we can test our endpoints, we need a user, so let’s create a seeder for the users table:

php artisan make:seeder UsersTableSeeder

Update the seeder to create a demo user, like this:

<?php
use App\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
DB::table('users')->truncate();
        User::create([
'name' => 'Demo User',
'email' => 'demo@example.org',
'email_verified_at' => now(),
'password' => bcrypt('secret'),
]);
}
}

Next, we’ll update our DatabaseSeeder to call our newly created UsersTableSeeder:

<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
$this->call(UsersTableSeeder::class);
}
}

Finally, seed the database:

php artisan db:seed

Perfect! We’re ready to start testing our endpoints.

Let’s make a post request to /api/login with the demo user’s credentials.

As you can see, we successfully logged in. Let’s verify that by making a request to the /api/user endpoint with the access_token from the previous request as the Authorization header.

Great! We have successfully verified that we’re logged in using Janitor with the Passport driver. Janitor comes along with a couple of other endpoints, you might want to try out:

  • /api/logout
  • /api/password/email
  • /api/password/reset

I’ll cover the email related endpoints in the next article, but you can try to set it up yourself. You can always refer to the package on Github for more documentation.

That was all for now. Thanks for reading along. In Part 2, I’ll show you how to use Janitor with a JWT driver that uses the tymon/jwt-auth package. The article will be published in May.

If you like the work I’ve done with Janitor, then don’t forget to star it on Github.

The example code for this project can be found following the link below: