3
votes

Laravel 5.3 Passport component looks pretty cool, but I have some confusion on it.

On documentation Passport is under API Authentication, and when set config/auth.php, it will change driver to be 'passport' of guards 'api'.

Laravel 5.3 have web.php and api.php to differ routes group to use web middleware or api middleware.

After installed Passport, there's a step to add Passport:routes() to AuthServiceProvider. When I run route:list it will show the new routes are all using web and auth middleware.

My question is why these passport routes using web middleware? For my understand Passport should work for stateless APIs authentication, but web middleware is not.

2

2 Answers

1
votes

I was facing this problem too until I realized my understanding of the working principle of passport is wrong.

Passport is about granting a client application the data of a user with the consent of that user (which is how OAuth2 works). So when a client app is trying to get the access-token that will eventually grant access to the data of that user, the consent of that user must be taken. The web middleware acts as a layer to take the consent of that user. To sign the consent the user must login first or there is will be no proof that it is an actual user.

To understand better, consider a scenario where your app is trying to implement the "Sign in with Google" feature. You put a button that redirects to Google in your login page, after redirecting, the user login into their Google account, sign a consent and gets redirected back to your app with an authorization code. This is just like that, here Google is the app you are building and the other app is the client app.

Still the best way to understand this if do a practical implementation. Just create a new app in laravel and put this code in the routes/web.php file.

Route::get('/redirect', function () {
    $query = http_build_query([
        'client_id' => 'YOUR APP'S CLIENT ID',
        'redirect_uri' => 'THE CALLBACK YOU GAVE DURING CREATING THE CLIENT',
        'response_type' => 'code',
        'scope' => '',
    ]);

    return redirect('http://your-app.com/oauth/authorize?'.$query);
});

Then visit the new app with the /redirect route. Make sure you main app is running too.

0
votes

I seem to have solved this.

First thing I did was add and configure a CORS middleware from here https://github.com/barryvdh/laravel-cors

Then I wrapped the Passport routes in a route group by editing app/Providers/AuthServiceProvider.php

/** 
 * Register any authentication / authorization services.
 *
 * @return void
 */
public function boot()
{   
    $this->registerPolicies();

    Route::group(['prefix' => 'api', 'middleware' => 'cors'], function() {

        Passport::routes();

    }); 
}

In theory, if you wanted to use the oauth service outside of your API, you could have two instances of the Passport routes, one with the /api prefix and the cors middleware, then one without, so you don't lose cross-origin protection when using oauth in the browser.