Install the Package
composer require platformsh/oauth2
(Note: Prefer platformsh/client if possible, but use this for direct OAuth2 control.)
Configure Environment Variables
Add these to .env:
PLATFORMSH_CLIENT_ID=your_client_id
PLATFORMSH_CLIENT_SECRET=your_client_secret
PLATFORMSH_REDIRECT_URI=https://your-app.com/platformsh-callback
First OAuth2 Flow Use the client to authenticate and fetch a token:
use Platformsh\OAuth2\Client;
$client = new Client(
env('PLATFORMSH_CLIENT_ID'),
env('PLATFORMSH_CLIENT_SECRET'),
env('PLATFORMSH_REDIRECT_URI')
);
// Get authorization URL (redirect user to Platform.sh)
$authUrl = $client->getAuthorizationUrl(['scope' => 'read:projects']);
// After callback, exchange code for token
$token = $client->getAccessToken('authorization_code', [
'code' => request('code')
]);
First API Request Attach the middleware to Guzzle and make a request:
use GuzzleHttp\Client;
$guzzle = new Client([
'middleware' => [$client->getMiddleware()],
'base_uri' => 'https://api.platform.sh/v1/'
]);
$response = $guzzle->get('projects');
$projects = json_decode($response->getBody(), true);
Middleware for Laravel HTTP Client
Extend Laravel’s HttpClient to include the OAuth2 middleware:
// app/Providers/AppServiceProvider.php
use Illuminate\Support\Facades\Http;
use Platformsh\OAuth2\Client;
public function boot()
{
Http::macro('platform', function () {
$client = new Client(
env('PLATFORMSH_CLIENT_ID'),
env('PLATFORMSH_CLIENT_SECRET'),
env('PLATFORMSH_REDIRECT_URI')
);
return Http::withOptions([
'middleware' => [$client->getMiddleware()],
'base_uri' => 'https://api.platform.sh/v1/'
]);
});
}
Usage:
$projects = Http::platform()->get('projects')->json();
Token Storage with Laravel Cache Store and retrieve tokens using Laravel’s cache:
// Store token
cache()->put('platformsh_token', $token, now()->addHours(1));
// Retrieve token
$token = cache()->get('platformsh_token');
if (!$token) {
$token = $client->refreshToken($client->getAccessToken());
cache()->put('platformsh_token', $token, now()->addHours(1));
}
Conditional Middleware Application Apply the middleware only to Platform.sh endpoints:
// app/Http/Middleware/PlatformAuthMiddleware.php
public function handle($request, Closure $next)
{
if ($request->is('api/platform/*')) {
$client = new Client(...);
$request->withMiddleware($client->getMiddleware());
}
return $next($request);
}
CI/CD Pipeline Authentication Authenticate API calls in GitHub Actions or GitLab CI:
# .github/workflows/deploy.yml
- name: Deploy to Platform.sh
run: |
php artisan platform:deploy
# Uses Http::platform() under the hood
Admin Dashboard Integration Fetch project data for a Laravel admin panel:
public function index()
{
$projects = Http::platform()->get('projects')->json();
return view('platform.dashboard', compact('projects'));
}
Webhook Verification Verify Platform.sh webhook signatures:
use Platformsh\OAuth2\Client;
$client = new Client(...);
$signature = $client->verifyWebhookSignature(
request()->header('X-Hub-Signature'),
request()->getContent()
);
Token Expiration Handling
$maxRetries = 3;
for ($i = 0; $i < $maxRetries; $i++) {
try {
return Http::platform()->get('projects')->json();
} catch (\League\OAuth2\Client\Provider\Exception\TokenExpiredException $e) {
$client->refreshToken($client->getAccessToken());
if ($i === $maxRetries - 1) throw $e;
}
}
Middleware Conflicts
// app/Facades/PlatformClient.php
public static function get($endpoint)
{
return Http::platform()->get($endpoint)->json();
}
Hardcoded Platform.sh URLs
$client = new Client(..., null, null, [
'url' => 'https://custom-platform.sh/oauth'
]);
Lack of Laravel Events
event(new PlatformTokenRefreshed($token));
Enable Guzzle Debugging
$guzzle = new Client([
'middleware' => [$client->getMiddleware()],
'debug' => true,
'handler' => GuzzleHttp\HandlerStack::create(new \GuzzleHttp\Middleware::tap(function ($request) {
\Log::debug('Request:', [$request->getUri(), $request->getHeaders()]);
}))
]);
Log Token Responses
$token = $client->getAccessToken('authorization_code', [
'code' => request('code')
]);
\Log::debug('Token response:', $token->toArray());
Validate Scopes Ensure your scopes match Platform.sh’s API requirements:
$authUrl = $client->getAuthorizationUrl([
'scope' => ['read:projects', 'write:environments']
]);
Custom Token Storage
Extend the Client class to use a custom storage backend:
class CustomClient extends Client {
public function getAccessToken($grantType, array $options = [])
{
$token = $this->storage->getToken();
if (!$token) {
$token = parent::getAccessToken($grantType, $options);
$this->storage->saveToken($token);
}
return $token;
}
}
Add Custom Headers Inject additional headers via middleware:
$client->getMiddleware()->addHeader('X-Custom-Header', 'value');
Mock for Testing Use a mock provider for unit tests:
$client = new Client($clientId, $clientSecret, $redirectUri, [
'provider' => new \League\OAuth2\Client\Provider\MockProvider()
]);
Redirect URI Validation
redirect_uri strictly. Ensure it matches exactly (including https vs. http).Token Cache TTL
$client = new Client(..., null, null, [
'tokenTTL' => 3600 // 1 hour
]);
Scope Requirements
read:projects). Always validate scopes before making requests.Token Refresh Overhead
cache()->forever('platformsh_token', $token);
Middleware Order
$stack = HandlerStack::create();
$stack->push($client->getMiddleware(), 'oauth2');
$guzzle = new Client(['handler' => $stack]);
How can I help you explore Laravel packages today?