kinetis / auth-jwt
Stateless JWT authentication middleware for Kinetis (HS256/RS256, optional per-token revocation), verifying signed tokens via firebase/php-jwt. See kinetis/auth instead for opaque Bearer-token validation against your own storage.
Requires
- php: ^8.4
- ext-openssl: *
- firebase/php-jwt: ^7.1.0
- kinetis/framework: ^1.13.0
- nyholm/psr7: ^1.8.2
- psr/http-message: ^2.0
- psr/http-server-middleware: ^1.0.2
- psr/simple-cache: ^3.0.0
Requires (Dev)
- infection/infection: ^0.35.0
- phpstan/phpstan: ^2.2.8
- phpunit/phpunit: ^13.3.3
- vimeo/psalm: ^6.17
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
kinetis/auth-jwt
Stateless JWT authentication middleware for Kinetis
Part of Kinetis, a non-blocking PHP framework for API-first applications, developed in the kinetis-dev/kinetis monorepo.
JwtAuthenticator holds the whole verification decision — a token in, a
JwtUser or null out — and a PSR-15 route middleware reads the
Authorization: Bearer <token> header, hands the credential over, and
registers the result on the current request as both
CurrentUserInterface and the concrete JwtUser (the identical object
either way — inject JwtUser directly when you need a claim beyond the
subject, roles or jti for instance). Plus an issuer for signing
tokens. Verification via
firebase/php-jwt
(HS256/RS256) — no required user or database lookup; the signed claims
are the authentication decision on their own. Configuring a revocation
store adds one optional per-token cache lookup.
// bootstrap.php — one configured authenticator, shared by every request. use Kinetis\AuthJwt\JwtAuthenticator; use Kinetis\AuthJwt\JwtVerificationKeys; $app->instance(JwtAuthenticator::class, new JwtAuthenticator( JwtVerificationKeys::hmacSecret($config->required('JWT_SECRET')), ));
use Kinetis\AuthJwt\JwtAuthMiddleware; use Kinetis\Http\Attributes\Get; use Kinetis\Http\Attributes\Middleware; use Kinetis\Http\CurrentUserInterface; #[Middleware(JwtAuthMiddleware::class)] final readonly class OrderController { public function __construct( private CurrentUserInterface $user, ) {} #[Get('/orders')] public function index(): array { return ['userId' => $this->user->id()]; } }
Keys are configured through one immutable value on each side:
JwtVerificationKeys::hmacSecret()/rsaPublicKey()/jwks() for the
authenticator, JwtSigningKey::hmacSecret()/rsaPrivateKey() for
JwtIssuer. Each names its own algorithm and key id, and validates the
material where it is written rather than on the first request.
Rotating signing keys: JwkSet publishes PublishedRsaKey values as an
RFC 7517 JWK Set for a .well-known/jwks.json route, and
JwtVerificationKeys::jwks() reads that document back into the keys a
token's own kid selects among — kids carried and matched as the exact
strings the document published, every key validated before the value
exists.
The middleware also describes itself to Kinetis's OpenAPI generator, so
every route it guards publishes security: [{"bearerJwt": []}] and the
matching HTTP bearer scheme without any further declaration. The name
and the definition are fixed: they describe the wire mechanism, not the
issuer, audience or keys a deployment verifies with.
Need opaque Bearer-token validation against your own storage instead?
See kinetis/auth.
Installation
composer require kinetis/auth-jwt
Requires PHP 8.4+ and kinetis/framework. Full documentation:
kinetis.dev/docs/auth-jwt.html.
License
MIT — see LICENSE.