adam78
adam78

Reputation: 10068

Laravel Passport: Add Auth Guard to Passport Routes?

Is there a way to overide the passport route middleware with your own auth guard?

In my boot method of the AuthServiceProvider I can do the following but it simply merges the middleware with the defaults (https://github.com/laravel/passport/blob/master/src/Passport.php) :

public function boot()
{
    $this->registerPolicies();

    Passport::routes(null, ['middleware' => 'auth:recruiters']);
}   

For example the above gives me the following middleware applied to the routes:

GET|HEAD | oauth/authorize |   | Laravel\Passport\Http\Controllers\AuthorizationController@authorize | auth:recruiters,web,auth   

I want to completely remove the auth middleware where it is applied to any passport routes and replace with auth:recruiter or any other guard.

In my config/auth.php I have my guards set up as follows - note the provider is the users table so the only thing I want to implement is to change the deafult auth in the passport routes by specifying a guard:

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

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

    'recruiter' => [
        'driver' => 'session',
        'provider' => 'users',
    ],


],

Do I need to write my own passport routes to achieve this and if so do i just stick them in the routes.php file and remove the Passport::routes() from the boot method?

Whats the callback option on the Passport::routes() method, can I use that perhaps to overide the existing routes?

public static function routes($callback = null, array $options = [])
{
    $callback = $callback ?: function ($router) {
        $router->all();
    };
    $defaultOptions = [
        'prefix' => 'oauth',
        'namespace' => '\Laravel\Passport\Http\Controllers',
    ];
    $options = array_merge($defaultOptions, $options);
    Route::group($options, function ($router) use ($callback) {
        $callback(new RouteRegistrar($router));
    });
}

Some guidance would be appreciated along with some code snippet for support.

Upvotes: 1

Views: 1831

Answers (1)

adam78
adam78

Reputation: 10068

Ok so I managed to do some kind of hack to apply my own auth guard as follows.

In my boot method I overide all the passport routes using the callback method:

public function boot()
{

    $guard = 'auth';
    $prefix = 'oauth';


    if ($this->app->request->is('recruiter/*')){
        $guard = 'auth:recruiter';
        $prefix = 'recruiter/oauth';
    }


    Passport::routes(function ($router) use ($guard) {

        // forAuthorization
        Route::group(['middleware' => ['web', $guard]], function ($router) {
            $router->get('/authorize', [
                'uses' => 'AuthorizationController@authorize',
            ]);
            $router->post('/authorize', [
                'uses' => 'ApproveAuthorizationController@approve',
            ]);
            $router->delete('/authorize', [
                'uses' => 'DenyAuthorizationController@deny',
            ]);
        });

        // all other routes...

   }, ['prefix' => $prefix]);

}

I also updated the urls for the out of the box vue components as follows by prepending a base url - in my case the base url defines the guard to use as well.

 getClients() {
     axios.get('/' + baseUrl + '/oauth/clients')
                    .then(response => {
                        this.clients = response.data;
     });
 },

I store the base url value in my master layout template inside a script tag as I have a different layout template for each type of user e.g:

<script>
        var baseUrl = "recruiter";
</script>

Lastly I amended the vendor/passport/authorize.blade.php file by updating the approve and cancel form urls as follows:

<form method="post" action="/{{ Request::segment(1) }}/oauth/authorize"> 

Now I can continue to use my multiauth set up.

Note this only works if your multi auth provider are all users

Upvotes: 1

Related Questions