Laravel Passport is the flagship OAuth server created by Taylor Otwell for the Laravel framework. It is simple to set up and use as are all packages made for Laravel by Taylor and the incredible Laravel community.
The same should be possible for Lumen, right? No, Laravel Passport’s Lumen support has never been released and there have been some walkarounds to do this. Some developers gave up and tried incorporating other third-party OAuth packages which are more complicated and may not have great support.
In this confusion, one man emerged and saved us all. His name is Denis Mysenko who built a lumen package suitably named Lumen Passport. This package was a lifesaver as it provides the much-needed support for Passport on Lumen. It is the best implementation so far as compared to the rest.
Let me save you the time to figure out how to setup things by providing this short tutorial. Follow the following steps and thank me later.
Install Lumen Passport in your Lumen project
Use composer command or install by adding it to composer.json file. Ensure the version matches the one below:
composer require dusterio/lumen-passport
Or add it to composer.json file:
{ "require": { "dusterio/lumen-passport": "^0.2.0" } } 2.Modify the bootstrap/app.php file
Uncomment the following lines:
// enable use of facades $app->withFacades();
// enable Eloquent $app->withEloquent();
// Load auth config files $app->configure('auth');
3. Create/modify the config/auth.php file and add the following code
return [ 'defaults' => [ 'guard' => 'api', 'passwords' => 'users', ], 'guards' => [ 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], ], 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => \App\User::class ] ] ];
4. Register service providers
$app->register(Laravel\Passport\PassportServiceProvider::class);
$app->register(Dusterio\LumenPassport\PassportServiceProvider::class);
5. Add CheckClientCredentials middleware to $routeMiddleware
$app->routeMiddleware([
'auth' => App\Http\Middleware\Authenticate::class,
'client' => \Laravel\Passport\Http\Middleware\CheckClientCredentials::class,
]);
Attach to your routes:
use Illuminate\Http\Request;
$router->get('/test_endpoint', function (Request $request) {
...
})->middleware('client');
or group your routes and give them all the middleware
$router->group(['prefix' => 'api/v1', 'middleware' => 'client'], function() use (&$router){ ... });
6. Run migrations
php artisan migrate
This creates several tables:
- auth_access_tokens - oauth_auth_codes - oauth_clients - oauth_personal_access_clients - oauth_refresh_tokens
7. Install passport
The following command is used to generate private and public encryption keys used for token generation and it also sets up the necessary routes. The keys are stored in the storage folder.
php artisan passport:install
8. Setup route prefix
This statement is added to your bootstrap/app.php file after registering the service providers.
Dusterio\LumenPassport\LumenPassport::routes($app->router, ['prefix' => 'api/v1/oauth'] );
Modify the prefix to match your preferences.
9. Add HasAPITokens Trait to your User model
use Laravel\Passport\HasApiTokens;
class User extends Model implements AuthenticatableContract, AuthorizableContract
{
use Authenticatable, Authorizable, HasApiTokens;
/* Rest of the model here */
}
Generating Tokens

You want some tokens, eh? They have been rumored to be stored deep in Treasure Island and only Jack Sparrow has ever seen them. Do not fear because I will show you thy way and magically generate for you your heart’s desire.
It is quite simple to generate your clients and access tokens.
Let us take an example, you have a mobile app that you would like to securely access an API on the backend. So which tokens would you generate?
The simple way is to consider your app as a client. The client has to be generated and issued the following:
client_id -> integer value client_secret -> alphanumeric value generated by Passport
This data is provided after issuing the following command which takes you through a step-by-step guide:
php artisan passport:client
The redirect url is a callback url you have to setup where after the user will be redirected to after authorization. In our case we’ll use a different command:
php artisan passport:client --client
This is because we do not have users involved and it’s only a machine-to-machine communication between our first-party client (mobile app) and our microservice API. This can also be used to generate clients for scheduled jobs on your servers that use your APIs.
This means, there is no need for your users to go through the entire OAuth2 authorization code redirect flow. Yay!
If you receive the following error, do not worry, I got you.
In Container.php line 945:
Target [Illuminate\Contracts\Routing\UrlGenerator] is not instantiable.
This is an issue in Lumen where the UrlGenerator
contract has not been bound to any instance, so you’ll have to do it manually.
Add this to your bootstrap/app.php file:
$app->bind(\Illuminate\Contracts\Routing\UrlGenerator::class, function ($app) {
return new \Laravel\Lumen\Routing\UrlGenerator($app);
});
Here is the full app.php file for comparison:
<?php require_once __DIR__.'/../vendor/autoload.php'; try { (new Dotenv\Dotenv(dirname(__DIR__)))->load(); } catch (Dotenv\Exception\InvalidPathException $e) { // } /* |-------------------------------------------------------------------------- | Create The Application |-------------------------------------------------------------------------- | | Here we will load the environment and create the application instance | that serves as the central piece of this framework. We'll use this | application as an "IoC" container and router for this framework. | */ $app = new Laravel\Lumen\Application( dirname(__DIR__) ); $app->instance('path.config', app()->basePath() . DIRECTORY_SEPARATOR . 'config'); $app->instance('path.storage', app()->basePath() . DIRECTORY_SEPARATOR . 'storage'); $app->withFacades(); $app->withEloquent(); $app->bind(\Illuminate\Contracts\Routing\UrlGenerator::class, function ($app) { return new \Laravel\Lumen\Routing\UrlGenerator($app); }); /* |-------------------------------------------------------------------------- | Register Container Bindings |-------------------------------------------------------------------------- | | Now we will register a few bindings in the service container. We will | register the exception handler and the console kernel. You may add | your own bindings here if you like or you can make another file. | */ $app->singleton( Illuminate\Contracts\Debug\ExceptionHandler::class, App\Exceptions\Handler::class ); $app->singleton( Illuminate\Contracts\Console\Kernel::class, App\Console\Kernel::class ); $app->configure('auth'); $app->configure('database'); /* |-------------------------------------------------------------------------- | Register Middleware |-------------------------------------------------------------------------- | | Next, we will register the middleware with the application. These can | be global middleware that run before and after each request into a | route or middleware that'll be assigned to some specific routes. | */ // $app->middleware([ // App\Http\Middleware\ExampleMiddleware::class // ]); $app->routeMiddleware([ 'auth' => App\Http\Middleware\Authenticate::class, ]); /* |-------------------------------------------------------------------------- | Register Service Providers |-------------------------------------------------------------------------- | | Here we will register all of the application's service providers which | are used to bind services into the container. Service providers are | totally optional, so you are not required to uncomment this line. | */ $app->register(App\Providers\AppServiceProvider::class); $app->register(App\Providers\AuthServiceProvider::class); $app->register(App\Providers\EventServiceProvider::class); $app->register(Flipbox\LumenGenerator\LumenGeneratorServiceProvider::class); $app->register(Laravel\Passport\PassportServiceProvider::class); $app->register(Dusterio\LumenPassport\PassportServiceProvider::class); $app->register(Illuminate\Redis\RedisServiceProvider::class); $app->register(BeyondCode\DumpServer\DumpServerServiceProvider::class); $app->register(Illuminate\Redis\RedisServiceProvider::class); Dusterio\LumenPassport\LumenPassport::routes($app->router, ['prefix' => 'api/v1/oauth'] ); /* |-------------------------------------------------------------------------- | Load The Application Routes |-------------------------------------------------------------------------- | | Next we will include the routes file so that they can all be added to | the application. This will provide all of the URLs the application | can respond to, as well as the controllers that may handle them. | */ $app->router->group([ 'namespace' => 'App\Http\Controllers', ], function ($router) { require __DIR__.'/../routes/web.php'; }); return $app;
After going through the steps, you should have a message like the one below:
Password grant client created successfully. Client ID: 3 Client Secret: RZZyELdtmVrFmujA7NLCep9srvSHsvz91bVTtnnh
We are almost there, in order to acquire your access tokens, we have to make a POST request to [api_prefix]/oauth/token
Remember to replace [api_prefix] with what you set in your bootstrap/app.php file.
Make your request using Postman, curl, httpie or whatever you use to test endpoints and make the request with the following application/json body:
{ "grant_type": "client_credentials", "scope": "*", "client_id": "[CLIENT_ID]", "client_secret": "[CLIENT_SECRET]" }
Replace the values of CLIENT_ID and CLIENT_SECRET with those you had generated using passport:client —client above.
You should now have your much-desired access tokens.
For more information, check out the official Lumen Passport and Laravel Passport docs.
You can also view all necessary files as GitHub gists.
If you would love to Buy me a Coffee, feel free to do so here.