Add support to multi-auth on Laravel Passport
smartins/passport-multiauth is a Laravel package for add support to multi-auth on laravel passport.
It currently has 285 GitHub stars and 327.395 downloads on Packagist (latest version v7.0.0).
Install it with composer require smartins/passport-multiauth.
Discover more Laravel packages by smartins
or browse all Laravel packages to compare alternatives.
Last updated
Add multi-authentication support to Laravel Passport
| Laravel Passport | |------------------| | ^3.0 | | ^4.0 | | ^5.0 | | ^6.0 |
$ composer require smartins/passport-multiauth
config/app.php: 'providers' => [
// ...
SMartins\PassportMultiauth\Providers\MultiauthServiceProvider::class,
],
oauth_access_token_providers table:$ php artisan migrate
config/auth.php using a model that extends of Authenticatable class and use HasApiTokens trait.Example:
use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable
{
use Notifiable, HasApiTokens;
}
config/auth.php providers: // ...
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
// ** New provider**
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
],
// ...
guard in config/auth.php guards array using driver passport and the provider added above: // ...
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
// ** New guard **
'admin' => [
'driver' => 'passport',
'provider' => 'admins',
],
],
// ...
AddCustomProvider to $routeMiddleware attributes on app/Http/Kernel.php file.
class Kernel extends HttpKernel
{
// ...
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
// ...
'oauth.providers' => \SMartins\PassportMultiauth\Http\Middleware\AddCustomProvider::class,
];
// ...
}
Authenticate on app/Http/Kernel $routeMiddleware attribute.
class Kernel extends HttpKernel
{
// ...
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
// 'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth' => \SMartins\PassportMultiauth\Http\Middleware\MultiAuthenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'oauth.providers' => \SMartins\PassportMultiauth\Http\Middleware\AddCustomProvider::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
// ...
}
AuthServiceProvider. This middleware will add the capability to Passport route oauth/token use the value of provider param on request:namespace App\Providers;
use Route;
use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
// ...
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Passport::routes();
// Middleware `oauth.providers` middleware defined on $routeMiddleware above
Route::group(['middleware' => 'oauth.providers'], function () {
Passport::routes(function ($router) {
return $router->forAccessTokens();
});
});
}
// ...
}
Optional: Publish migrations:
Just run the vendor:publish artisan command with package provider as parameter:
$ php artisan vendor:publish --provider="SMartins\PassportMultiauth\Providers\MultiauthServiceProvider"
provider parameter in your request at /oauth/token:POST /oauth/token HTTP/1.1
Host: localhost
Accept: application/json, text/plain, */*
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache
{
"username":"[email protected]",
"password":"password",
"grant_type" : "password",
"client_id": "client-id",
"client_secret" : "client-secret",
"provider" : "admins"
}
auth middleware as you wish. Example:Route::group(['middleware' => ['api', 'auth:admin']], function () {
Route::get('/admin', function ($request) {
// Get the logged admin instance
return $request->user(); // You can use too `$request->user('admin')` passing the guard.
});
});
The api guard use is equals the example with admin.
auth middleware.Route::group(['middleware' => ['api', 'auth:admin,api']], function () {
Route::get('/admin', function ($request) {
// The instance of user authenticated (Admin or User in this case) will be returned
return $request->user();
});
});
You can use too the Auth facade:
Auth::check();
Auth::user();
provider parameter in your request at /oauth/token:POST /oauth/token HTTP/1.1
Host: localhost
Accept: application/json, text/plain, */*
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache
{
"grant_type" : "refresh_token",
"client_id": "client-id",
"client_secret" : "client-secret",
"refresh_token" : "refresh-token",
"provider" : "admins"
}
scope and scopes middlewares from Laravel\Passport.protected $routeMiddleware = [
'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class,
'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class,
];
Instead to use the Laravel\Passport\Passport::actingAs() method, use SMartins\PassportMultiauth\PassportMultiauth::actingAs().
The difference is that the actingAs from this package get the guard based on Authenticatable instance passed on first parameter and authenticate this user using your guard. On authenticated request (Using auth middleware from package - SMartins\PassportMultiauth\Http\Middleware\MultiAuthenticate) the guard is checked on Request to return the user or throws a Unauthenticated exception. E.g.:
use App\User;
use Tests\TestCase;
use SMartins\PassportMultiauth\PassportMultiauth;
class AuthTest extends TestCase
{
public function fooTest()
{
$user = factory(User::class)->create();
PassportMultiauth::actingAs($user);
$this->json('GET', 'api/user');
}
public function withScopesTest()
{
$user = factory(User::class)->create();
PassportMultiauth::actingAs($user, ['see-balance']);
$this->json('GET', 'api/balance');
}
}
Based on renanwilian responses to Passport Multi-Auth issue.