spomky-labs/oauth2-interface
PHP interfaces and contracts for building OAuth2 authorization and resource servers. This package defines the core abstractions used across the Spomky-Labs OAuth2 framework, letting you implement standards-compliant flows with your own storage, clients, and token handlers.
spomky-labs/oauth2-interface is a contracts-only package: it ships PHP interfaces (and a few supporting traits) under the OAuth2\ namespace, but no working server, no storage, no crypto, and no HTTP layer. Think of it as the "shape" that an OAuth2 implementation must fit into, not the implementation itself.
composer require spomky-labs/oauth2-interface
Before you install it, be clear on why. The realistic reasons are:
spomky-labs/oauth2-server and oauth2-server-bundle).ClientInterface, AccessTokenInterface, repository interfaces) so your application code does not depend on a concrete server library.Where to look first. Open the src/ tree and read it top-down. It is small and grouped by concern, roughly:
OAuth2\Client\ — ClientInterface, ClientRepositoryInterfaceOAuth2\EndUser\ — EndUserInterface, EndUserManagerInterfaceOAuth2\Scope\ — ScopeInterface, ScopeManagerInterfaceOAuth2\Token\ — AccessTokenInterface, RefreshTokenInterface, and their manager interfacesOAuth2\Grant\ — grant type contractsOAuth2\Endpoint\ — authorization/token endpoint contractsOAuth2\Exception\ — the OAuth2 exception contractFirst use case. The smallest useful thing you can do is implement ClientRepositoryInterface for your persistence layer and return an object implementing ClientInterface. That single bridge is what lets an authorization/token endpoint look up a client by ID without knowing whether you use Doctrine, Eloquent, or an in-memory array. If you cannot wire that up cleanly, the package is probably not the right foundation for your project.
Implement the entity interfaces on your own models. Do not expect the package to give you base classes. Attach ClientInterface, AccessTokenInterface, ScopeInterface, etc. to your domain entities and map them in your ORM. Keep the OAuth2 concerns (secret, redirect URIs, grant types, scopes, expiry) on those entities and let the interfaces be the boundary.
Implement the repository/manager interfaces as adapters. The typical split is:
*RepositoryInterface → read/write persistence (find client, find token, revoke token).*ManagerInterface → orchestration that a server would call (issue token, validate scope).Write these as thin adapters over your existing repositories. Keep them free of business logic that belongs in your application services; the interface package gives you no opinions here, so you own the semantics.
Depend on interfaces, not implementations, in your services. This is the real day-to-day leverage. Type-hint ClientRepositoryInterface or AccessTokenInterface in your controllers/services and bind a concrete implementation in your container. When you later swap the underlying OAuth2 server (or write a test double), your application code is unchanged.
final class TokenIssuer
{
public function __construct(private AccessTokenManagerInterface $tokens) {}
public function issue(ClientInterface $client, EndUserInterface $user): AccessTokenInterface
{
return $this->tokens->create($client, $user, /* scopes, ttl */);
}
}
Custom grant types. Implement the grant type contract and register it with your concrete server. The interface package defines the shape; the concrete library (historically oauth2-server) is what actually invokes it, so verify the exact method signatures against the version of the implementation you pair it with — do not assume the interface alone is sufficient.
Testing. This is where interface-only packages shine. Mock ClientRepositoryInterface, AccessTokenInterface, ScopeManagerInterface in unit tests and exercise your authorization/token logic without a database or a running server. This is arguably the most common real-world use of the package today.
Version your dependency. Pin the interface package and the concrete implementation together in composer.json, and add a comment linking the compatibility matrix. Because the interfaces evolve independently of any server, a minor bump can break an implementing class.
league/oauth2-server (and oauth2-server-bundle), which is actively maintained and has a much larger user base. For a greenfield project, prefer league/oauth2-server and its contracts. Use spomky-labs/oauth2-interface only if you are maintaining an existing Spomky-based stack.findClient return null or throw on miss?) rather than guessing from the interface. Normalize this at your adapter boundary.OAuth2 exception interface but the mapping to RFC 6749 error responses (invalid_request, invalid_grant, etc.) is your responsibility. Centralize this mapping in one place so the token endpoint and authorization endpoint stay consistent.league/oauth2-server (or a framework integration of it) unless you have a hard dependency on the Spomky interfaces. If you must keep the Spomky contract for backward compatibility, isolate it behind your own application-level interfaces so a future migration is a matter of swapping adapters, not rewriting call sites.How can I help you explore Laravel packages today?