spomky-labs/oauth2-server-public-client-bundle
Symfony bundle that adds public client support to the Spomky-Labs OAuth2 server, enabling clients that cannot keep secrets—such as mobile and browser-based apps—to obtain tokens securely with authorization code and PKCE flows and integrate easily into Symfony applications.
This bundle is an add-on to spomky-labs/oauth2-server-bundle. It does not implement OAuth2 itself; it registers the "public client" (no client secret) client type and the supporting manager so the parent bundle can issue tokens to mobile apps, SPAs, and CLIs that cannot safely store a secret.
Minimal steps:
composer require spomky-labs/oauth2-server-bundle
composer require spomky-labs/oauth2-server-public-client-bundle
app/AppKernel.php after the parent bundle, since it decorates/extends services the parent declares:
new SpomkyLabs\Bundle\OAuth2ServerBundle\OAuth2ServerBundle(),
new SpomkyLabs\Bundle\OAuth2ServerPublicClientBundle\OAuth2ServerPublicClientBundle(),
config.yml. The bundle mostly exposes a service (a public-client manager / client type) via DependencyInjection/ and Resources/config/services.xml. Run app/console container:debug | grep -i oauth2 to see the exact service IDs and aliases rather than trusting the README naming.authorization_code (plus refresh_token), and point your SPA/mobile app at the parent bundle's /oauth/v2/auth and /oauth/v2/token endpoints.Pair it with the parent bundle's config. Grants, scopes, and storage live in spomky-labs/oauth2-server-bundle. This bundle only changes how clients authenticate (by client_id + redirect_uri instead of client_id/client_secret).
Client definitions. Public clients should be stored with a null/empty secret and flagged as public in your client manager. Keep the allowed-grant list per client, not global — a public client must never be allowed client_credentials or password.
Typical authorization-code flow (public client):
GET /oauth/v2/auth?response_type=code
&client_id=mobile-app
&redirect_uri=https://app.example/cb
&scope=read
[&code_challenge=...&code_challenge_method=S256] // if PKCE support is present
POST /oauth/v2/token
grant_type=authorization_code
&client_id=mobile-app
&code=...
&redirect_uri=https://app.example/cb
// no client_secret
If the parent library version is old enough that PKCE is unavailable, fall back to strict exact-match redirect URIs.
Custom client manager. The most common integration is replacing the default manager with your own (Doctrine entity, config-driven array, etc.) and decorating it to assert isPublic() semantics. Alias your implementation over the service ID the bundle registers.
API protection stays unchanged. Resource-server firewalls and token validation are the parent bundle's job; tokens from public clients are validated identically. In tests, hit the auth and token endpoints with a public client and assert the absence of client_secret succeeds and that passing one is ignored/rejected consistently.
league/oauth2-server with oauth2-server-bundle/FOSOAuthServerBundle. Use this only to maintain a legacy app; do not start new work on it.redirect_uri to a whitelist.invalid_client) usually mean the client manager is still requiring a secret or the client record lacks the public flag. Check the manager, not the bundle config.spomky_labs_*, oauth2_server_*). Always confirm with container:debug; the docs and the actual IDs drift between versions.How can I help you explore Laravel packages today?