blcklab/panulat-jwt

Lightweight JWT authentication package for Panulat REST APIs.

Maintainers

Package info

github.com/blcklab/panulat-jwt

pkg:composer/blcklab/panulat-jwt

Transparency log

Statistics

Installs: 15

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.0 2026-07-06 21:46 UTC

This package is auto-updated.

Last update: 2026-07-06 21:54:38 UTC


README

Packagist version downloads CI license

Panulat JWT

Lightweight JWT authentication for Panulat REST APIs.

blcklab/panulat-jwt adds JWT support to Panulat through a service provider, middleware, and route middleware aliases.

Install

composer require blcklab/panulat-jwt

blcklab/panulat-core is installed automatically as a package dependency.

Register the Provider

Add the JWT service provider to your Panulat application providers:

Panulat\Jwt\JwtServiceProvider::class

The provider registers:

  • Panulat\Jwt\JwtService
  • Panulat\Jwt\JwtMiddleware
  • auth middleware alias
  • jwt middleware alias

Configuration

The JWT service uses your application JWT configuration.

Example:

return [
    'secret' => panulat_env('JWT_SECRET', 'change-me'),
    'ttl' => 3600,
];

For production, always use a strong secret:

JWT_SECRET=your-secure-random-secret

Creating Tokens

use Panulat\Jwt\JwtService;

$jwt = new JwtService('your-secret-key');

$token = $jwt->encode([
    'sub' => '1',
    'email' => 'user@example.com',
    'exp' => time() + 3600,
]);

Decoding Tokens

$claims = $jwt->decode($token, ['sub']);

The second argument defines the required claims. If a required claim is missing, or if the token is invalid, a JWT exception is thrown.

Protecting Routes

Use the auth or jwt middleware alias to protect routes:

$router->get('/v1/me', [MeController::class, 'show'], ['auth']);

or:

$router->get('/v1/me', [MeController::class, 'show'], ['jwt']);

The middleware reads the bearer token from the request header:

Authorization: Bearer <token>

Request Attributes

After a valid token is decoded, the middleware attaches JWT data to the request:

$request->getAttribute('user');
$request->getAttribute('jwt_claims');

user contains the resolved user value from the token when available.

jwt_claims contains the decoded token claims.

Example Controller

use Panulat\Http\Request;
use Panulat\Http\Response;

final class MeController
{
    public function show(Request $request): Response
    {
        return Response::json([
            'data' => [
                'user' => $request->getAttribute('user'),
                'claims' => $request->getAttribute('jwt_claims'),
            ],
        ]);
    }
}

Error Handling

Invalid, expired, missing, or malformed tokens are converted into Panulat unauthorized responses by the middleware.

Typical response status:

401 Unauthorized

Scope

This package intentionally stays small.

Included:

  • HS256 JWT encode and decode support
  • JWT validation
  • Expiration handling
  • Required claim checks
  • Panulat middleware integration
  • auth and jwt middleware aliases

Not included:

  • OAuth
  • Sessions
  • Refresh token storage
  • Database token blacklist
  • Roles and permissions
  • Social login

Those features can be added through separate packages or application code.

Quality Checks

composer stan
composer test
composer check

License

MIT