Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Oauth2 Laravel Package

platformsh/oauth2

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the Package

    composer require platformsh/oauth2
    

    (Note: Prefer platformsh/client if possible, but use this for direct OAuth2 control.)

  2. 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
    
  3. 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')
    ]);
    
  4. 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);
    

Implementation Patterns

Laravel-Specific Workflows

  1. 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();
    
  2. 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));
    }
    
  3. 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);
    }
    

Common Use Cases

  1. 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
    
  2. 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'));
    }
    
  3. Webhook Verification Verify Platform.sh webhook signatures:

    use Platformsh\OAuth2\Client;
    
    $client = new Client(...);
    $signature = $client->verifyWebhookSignature(
        request()->header('X-Hub-Signature'),
        request()->getContent()
    );
    

Gotchas and Tips

Pitfalls

  1. Token Expiration Handling

    • Issue: Silent failures if tokens expire without refresh.
    • Fix: Wrap API calls in a retry loop:
      $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;
          }
      }
      
  2. Middleware Conflicts

    • Issue: Guzzle middleware may conflict with Laravel’s built-in HTTP client.
    • Fix: Use a facade to abstract the client:
      // app/Facades/PlatformClient.php
      public static function get($endpoint)
      {
          return Http::platform()->get($endpoint)->json();
      }
      
  3. Hardcoded Platform.sh URLs

    • Issue: The package assumes Platform.sh’s OAuth2 endpoint structure.
    • Fix: Override the provider URL if needed:
      $client = new Client(..., null, null, [
          'url' => 'https://custom-platform.sh/oauth'
      ]);
      
  4. Lack of Laravel Events

    • Issue: No built-in events for token refresh or API failures.
    • Fix: Dispatch custom events:
      event(new PlatformTokenRefreshed($token));
      

Debugging Tips

  1. 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()]);
        }))
    ]);
    
  2. Log Token Responses

    $token = $client->getAccessToken('authorization_code', [
        'code' => request('code')
    ]);
    \Log::debug('Token response:', $token->toArray());
    
  3. Validate Scopes Ensure your scopes match Platform.sh’s API requirements:

    $authUrl = $client->getAuthorizationUrl([
        'scope' => ['read:projects', 'write:environments']
    ]);
    

Extension Points

  1. 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;
        }
    }
    
  2. Add Custom Headers Inject additional headers via middleware:

    $client->getMiddleware()->addHeader('X-Custom-Header', 'value');
    
  3. Mock for Testing Use a mock provider for unit tests:

    $client = new Client($clientId, $clientSecret, $redirectUri, [
        'provider' => new \League\OAuth2\Client\Provider\MockProvider()
    ]);
    

Configuration Quirks

  1. Redirect URI Validation

    • Platform.sh validates the redirect_uri strictly. Ensure it matches exactly (including https vs. http).
  2. Token Cache TTL

    • Default token TTL may not match Platform.sh’s requirements. Adjust in the provider config:
      $client = new Client(..., null, null, [
          'tokenTTL' => 3600 // 1 hour
      ]);
      
  3. Scope Requirements

    • Some Platform.sh endpoints require specific scopes (e.g., read:projects). Always validate scopes before making requests.

Performance Considerations

  1. Token Refresh Overhead

    • Frequent token refreshes can slow down requests. Cache tokens aggressively:
      cache()->forever('platformsh_token', $token);
      
  2. Middleware Order

    • Ensure the OAuth2 middleware runs after Laravel’s default middleware but before request processing:
      $stack = HandlerStack::create();
      $stack->push($client->getMiddleware(), 'oauth2');
      $guzzle = new Client(['handler' => $stack]);
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
babenkoivan/elastic-client
innmind/static-analysis
innmind/coding-standard
datacore/hub-sdk
alengo/sulu-http-cache-bundle
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
imbo/imbo-coding-standard
visualbuilder/filament-lottie
servicioslineaonce/starter-kit
atomcoder/laravel-reorderable
irajul/filament-shadcn-theme
agtp/agtp-php
agtp/mod-php
centraldesktop/protobuf-php