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

Php Openid Client Laravel Package

facile-it/php-openid-client

Full-featured PHP OpenID Connect/OAuth2 client with discovery and dynamic client registration. Supports authorization flows, refresh/client credentials grants, userinfo & ID tokens, JWT signing/encryption, request objects, token revocation/introspection, and advanced client auth.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Install the package**:
   ```bash
   composer require facile-it/php-openid-client

Ensure your project meets PSR-7 requirements (e.g., guzzlehttp/psr7 or nyholm/psr7).

  1. Configure a basic client:

    use Facile\OpenIDClient\Client\ClientBuilder;
    use Facile\OpenIDClient\Issuer\IssuerBuilder;
    use Facile\OpenIDClient\Client\Metadata\ClientMetadata;
    
    $issuer = (new IssuerBuilder())->build('https://provider.com/.well-known/openid-configuration');
    $clientMetadata = ClientMetadata::fromArray([
        'client_id'     => 'your-client-id',
        'client_secret' => 'your-client-secret',
        'redirect_uris' => ['https://your-app.com/callback'],
    ]);
    $client = (new ClientBuilder())
        ->setIssuer($issuer)
        ->setClientMetadata($clientMetadata)
        ->build();
    
  2. First use case: Redirect to OpenID provider:

    $authorizationService = (new AuthorizationServiceBuilder())->build();
    $authUrl = $authorizationService->getAuthorizationUri($client, ['scope' => 'openid profile']);
    return redirect($authUrl);
    
  3. Handle callback:

    $callbackParams = $authorizationService->getCallbackParams($request, $client);
    $tokenSet = $authorizationService->callback($client, $callbackParams);
    

Implementation Patterns

1. Middleware Integration (Laravel Example)

Use the middleware stack to handle OAuth flows seamlessly:

// app/Http/Middleware/AuthenticateWithOpenID.php
use Facile\OpenIDClient\Middleware\SessionCookieMiddleware;
use Facile\OpenIDClient\Middleware\AuthRedirectHandler;
use Facile\OpenIDClient\Middleware\CallbackMiddleware;
use Facile\OpenIDClient\Middleware\UserInfoMiddleware;

public function handle($request, Closure $next) {
    $middleware = app(SessionCookieMiddleware::class);
    $middleware->process($request, function ($request) use ($next) {
        $middleware = app(AuthRedirectHandler::class);
        return $middleware->process($request, function ($request) use ($next) {
            return $next($request);
        });
    });
    return $next($request);
}

2. Service Layer Abstraction

Create a dedicated service class to encapsulate OpenID logic:

// app/Services/OpenIDService.php
class OpenIDService {
    public function __construct(
        private AuthorizationService $authService,
        private UserInfoService $userInfoService,
        private Client $client
    ) {}

    public function authenticate(Request $request) {
        $callbackParams = $this->authService->getCallbackParams($request, $this->client);
        $tokenSet = $this->authService->callback($this->client, $callbackParams);
        return $this->userInfoService->getUserInfo($this->client, $tokenSet);
    }
}

3. Dynamic Client Registration

Register clients dynamically at runtime:

$registrationService = (new RegistrationServiceBuilder())->build();
$metadata = $registrationService->register($issuer, [
    'client_name' => 'Laravel App',
    'redirect_uris' => ['https://app.com/callback'],
    'token_endpoint_auth_method' => 'client_secret_basic',
]);

4. Token Management

Handle token refresh and revocation:

// Refresh token
$tokenSet = $authService->refresh($client, $oldTokenSet->getRefreshToken());

// Revoke token
$revocationService = (new RevocationServiceBuilder())->build();
$revocationService->revoke($client, $tokenSet->getAccessToken());

5. Request Objects for Security

Use signed request objects for enhanced security:

$requestObject = (new RequestObjectFactory())->create($client, [
    'nonce' => bin2hex(random_bytes(16)),
    'acr_values' => ['urn:mace:incommon:iap:silver'],
]);
$authRequest = AuthRequest::fromParams([
    'client_id' => $client->getMetadata()->getClientId(),
    'redirect_uri' => $client->getMetadata()->getRedirectUris()[0],
    'request' => $requestObject,
]);

Gotchas and Tips

1. Common Pitfalls

  • State/Nonce Mismatch: Always use SessionCookieMiddleware to persist state and nonce parameters. Failure to validate these can lead to CSRF attacks.

    // Ensure this is the first middleware in your stack
    $middleware = new SessionCookieMiddleware(app('cache.store'));
    
  • Redirect URI Mismatch: The redirect_uris in your client metadata must exactly match the callback URL used in the authorization request. Typos here will break the flow.

  • Token Introspection vs. UserInfo: Introspection (/introspect) validates tokens, while UserInfo (/userinfo) fetches claims. Don’t confuse the two:

    // Introspect (validate)
    $introspectionService->introspect($client, $token);
    
    // UserInfo (fetch claims)
    $userInfoService->getUserInfo($client, $tokenSet);
    
  • JWKS Caching: The library caches JWKS (JSON Web Key Sets) by default for 1 day. Adjust the TTL in production if your provider updates keys frequently:

    $jwksProviderBuilder->setCacheTtl(3600); // 1 hour
    

2. Debugging Tips

  • Enable Verbose Logging: Use Monolog to log HTTP requests/responses for debugging:

    $clientBuilder->setHttpClient(new \GuzzleHttp\Client([
        'handler' => \GuzzleHttp\HandlerStack::create(new \GuzzleHttp\Middleware::log(
            app('logger')->getHandler(),
            new \GuzzleHttp\MessageFormatter()
        )),
    ]));
    
  • Validate Token Claims: Manually verify ID tokens before trusting them:

    $idToken = $tokenSet->getIdToken();
    $claims = $idToken->getClaims();
    if ($claims['iss'] !== $issuer->getIssuer() || $claims['aud'] !== $client->getMetadata()->getClientId()) {
        throw new \RuntimeException('Invalid token issuer or audience');
    }
    
  • Handle Missing Scopes: Always check if the openid scope is included in the authorization request. Without it, the provider won’t return an ID token:

    $authUrl = $authService->getAuthorizationUri($client, ['scope' => 'openid profile email']);
    

3. Performance Optimization

  • Cache Issuer Metadata: Cache the OpenID configuration metadata to avoid repeated HTTP calls:

    $metadataProviderBuilder->setCache(app('cache'))->setCacheTtl(86400); // 24 hours
    
  • Reuse HTTP Clients: Instantiate HTTP clients (e.g., Guzzle) once and reuse them across requests to avoid connection overhead:

    $httpClient = new \GuzzleHttp\Client(['timeout' => 10]);
    $clientBuilder->setHttpClient($httpClient);
    

4. Extension Points

  • Custom Claim Handling: Extend the ClaimsParser interface to handle provider-specific claims:

    class CustomClaimsParser implements ClaimsParserInterface {
        public function parse(array $claims, Client $client): array {
            // Add custom logic (e.g., transform provider-specific fields)
            return $claims;
        }
    }
    
  • Middleware Chaining: Combine middlewares for complex flows (e.g., pre-auth validation + post-auth actions):

    $middlewareStack = [
        new SessionCookieMiddleware($cache),
        new ClientProviderMiddleware($client),
        new AuthRequestProviderMiddleware($authRequest),
        new AuthRedirectHandler($authService),
        new CallbackMiddleware($authService),
        new UserInfoMiddleware($userInfoService),
    ];
    
  • Dynamic Client Metadata: Use the ClientMetadata builder to dynamically set metadata (e.g., for multi-tenant apps):

    $metadata = ClientMetadata::fromArray([
        'client_id' => $tenant->client_id,
        'client_secret' => $tenant->client_secret,
        'redirect_uris' => [$tenant->callback_url],
    ]);
    

5. Laravel-Specific Quirks

  • Session Driver: Ensure your Laravel session driver is PSR-16 compatible (e.g., array, database, or redis) for SessionCookieMiddleware:

    // config/cache.php
    'default' => env('CACHE_DRIVER', 'array'),
    
  • Service Provider Binding: Bind the library’s services in a service provider:

    // app/Providers/OpenIDServiceProvider.php
    public function register() {
        $this->app->
    
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor