I am working in two apps: accounts.domain.com (Laravel app) and dash.domain.com (Not laravel, but php). I want dash users to login through accounts to use the app, so I figured I could use OAuth to achieve this.
I installed Laravel Passport and everything worked fine when getting an authorization code:
$query = http_build_query([
'client_id' => $clientId,
'redirect_uri' => $redirectUri,
'response_type' => 'code',
'scope' => '*',
'state' => $state,
]);
return redirect('https://accounts.domain.com/oauth/authorize?'.$query);
But then I tried to get the access token:
$response = $http->post('https://accounts.domain.com/oauth/token', [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => $clientId,
'client_secret' => $clientSecret,
'redirect_uri' => $redirectUri,
'code' => $code,
],
]);
And I got this error:
{
"error": "invalid_client",
"error_description": "Client authentication failed",
"message": "Client authentication failed"
}
So I googled the error, and I found that maybe there was an error with my credentials, so I check them, tried to recreate them, and nothing.
Finally I got to this file vendor/laravel/passport/src/Bridge/ClientRepository.php and I found something really interesting in the handlesGrant method that is used to verify a client:
protected function handlesGrant($record, $grantType)
{
// ...
switch ($grantType) {
case 'authorization_code':
return ! $record->firstParty();
// ...
default:
return true;
}
}
I changed this line
return ! $record->firstParty();
To this:
return $record->firstParty();
And everything worked. So, what I can see is that, using 'grant_type' => 'authorization_code' is only valid for third party clients.
My question is: ¿Why can't first party clients use 'authorization_code' as grant type? And if they can, ¿how can I implement this without changing Laravel Passport files?