In this article, I will share how to configure Laravel application to act as an OAuth client, connecting to two other laravel projects which will act as OAuth servers. Our example includes Project A and Project B as OAuth servers, and Project C as OAuth client.
+------------+ +------------+
| Project | | Project |
| A | <------+------> | B |
+------------+ | +------------+
|
|
v
+-------------+
| Project |
| C |
+-------------+By following these steps, we will be able to configure the OAuth servers and get the access token from both servers seamlessly.
Step 1: Installing Laravel Passport Package
To begin, you need to install the Laravel Passport package in the project that you want to configure as an OAuth server.
Run the following commands within the Project A and Project B servers:
composer require laravel/passportphp artisan migratephp artisan passport:install --uuidsStep 2: Modifying User Model and Configurations
- Add the
Laravel\Passport\HasApiTokenstrait to yourApp\Models\Usermodel. - Modify the
auth.phpconfiguration file and define an API authentication guard, setting the driver option topassport. Refer to the official documentation for detailed guidance.
Step 3: Generating Passport Keys
For first-time deployment of Passport to your application servers, run the passport:keys command:
php artisan passport:keysStep 4: Routes and Controller in Project C (OAuth Client)
Route::group(['prefix' => 'api/{server}'], function () {
Route::get('/oauth/authorize',
[OAuthController::class, 'authorizeClient']
)->name('oauth.authorize');
Route::get('/oauth/callback',
[OAuthController::class, 'redirectCallback']
)->name('oauth.callback');
})->middleware(['auth']);And let’s see the OAuth Controller,
class OAuthController extends Controller
{
use OAuthHelpers;
public function authorizeClient(Request $request, $server)
{
.....
return redirect($this->serverAppUrl($server).'/oauth/authorize?'.$query);
}
public function redirectCallback(Request $request, $server)
{
.....
return to_route('where-you-want-to-redirect');
}
}Step 4: Creating OAuth Clients, in Project A and B
Execute the following command to create OAuth clients for the Project A and Project B apps:
php artisan passport:clientWhen asked about the redirect url, make sure to set the correct redirect URL, as this will be the URL we will be redirected once authorized on in Project A, and Project B.
Step 5: Let’s complete the OAuthController in Project C
class OAuthController extends Controller
{
use OAuthHelpers;
public function authorizeClient(Request $request, $server)
{
$request->session()->put('state', $state = Str::random(40));
$query = http_build_query([
'client_id' => $this->clientId($server),
'redirect_uri' => $this->clientRedirectUri($server),
'response_type' => 'code',
'scope' => '',
'state' => $state,
'prompt' => 'no',
]);
return redirect($this->serverAppUrl($server).'/oauth/authorize?'.$query);
}
public function redirectCallback(Request $request, $server)
{
$state = $request->session()->pull('state');
throw_unless(
strlen($state) > 0 && $state === $request->state,
InvalidArgumentException::class
);
$response = Http::post($this->serverAppUrl($server).'/oauth/token', [
'grant_type' => 'authorization_code',
'client_id' => $this->clientId($server),
'client_secret' => $this->clientSecret($server),
'redirect_uri' => $this->clientRedirectUri($server),
'code' => $request->code,
]);
$data = $response->json();
if (isset($data['access_token'])) {
$request->user()->createOauthToken([
'expires_in' => $data['expires_in'] ?? null,
'access_token' => $data['access_token'] ?? null,
'refresh_token' => $data['refresh_token'] ?? null,
]);
}
return to_route('where-you-want-to-redirect');
}
}Final Note
Once we have the “access_token” from each OAuth server, and we have stored it in the Project C’s database, we can use it in subsequent requests to pull data from Project A and Project B.
Remember, these steps outline the process for connecting Laravel application to two OAuth servers (which are themselves Laravel projects). Adjust URLs, client IDs, and secrets based on the specific use case and requirement.