PHPackages                             blcklab/panulat-jwt - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. blcklab/panulat-jwt

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

blcklab/panulat-jwt
===================

Lightweight JWT authentication package for Panulat REST APIs.

v0.1.0(1mo ago)0151MITPHP ^8.3

Since Jul 6Compare

[ Source](https://github.com/blcklab/panulat-jwt)[ Packagist](https://packagist.org/packages/blcklab/panulat-jwt)[ RSS](/packages/blcklab-panulat-jwt/feed)WikiDiscussions Synced 1w ago

READMEChangelogDependencies (4)Versions (2)Used By (1)

 [![Packagist version](https://camo.githubusercontent.com/b4c010af075c19c22942c30e6ac8d0baebe9e772670584f051b29af3f5327765/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f626c636b6c61622f70616e756c61742d6a77743f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/b4c010af075c19c22942c30e6ac8d0baebe9e772670584f051b29af3f5327765/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f626c636b6c61622f70616e756c61742d6a77743f7374796c653d666c61742d737175617265) [![downloads](https://camo.githubusercontent.com/a2b0bec205a0eac88d1a2d4daa72e38b7a75b29d6642118117e5830188733904/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646d2f626c636b6c61622f70616e756c61742d6a77743f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/a2b0bec205a0eac88d1a2d4daa72e38b7a75b29d6642118117e5830188733904/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646d2f626c636b6c61622f70616e756c61742d6a77743f7374796c653d666c61742d737175617265) [![CI](https://github.com/blcklab/panulat-jwt/actions/workflows/ci.yml/badge.svg)](https://github.com/blcklab/panulat-jwt/actions/workflows/ci.yml/badge.svg) [![license](https://camo.githubusercontent.com/c0ea9ddcfc0b0539b27a5435d12c0507982b3df378be6c4175ea2ec77bca3ca7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f626c636b6c61622f70616e756c61742d6a77743f763d32)](https://camo.githubusercontent.com/c0ea9ddcfc0b0539b27a5435d12c0507982b3df378be6c4175ea2ec77bca3ca7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f626c636b6c61622f70616e756c61742d6a77743f763d32)

Panulat JWT
===========

[](#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
-------

[](#install)

```
composer require blcklab/panulat-jwt
```

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

Register the Provider
---------------------

[](#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
-------------

[](#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
---------------

[](#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
---------------

[](#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
-----------------

[](#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
```

Request Attributes
------------------

[](#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
------------------

[](#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
--------------

[](#error-handling)

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

Typical response status:

```
401 Unauthorized
```

Scope
-----

[](#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
--------------

[](#quality-checks)

```
composer stan
composer test
composer check
```

License
-------

[](#license)

MIT

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance90

Actively maintained with recent releases

Popularity6

Limited adoption so far

Community5

Small or concentrated contributor base

Maturity38

Early-stage or recently created project

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

48d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/dc45b8a2e59ef460b4196fe4a8fed4402aee0fb8874c90c65fdae8e76ee1b7fe?d=identicon)[blcklab](/maintainers/blcklab)

---

Tags

phpjwtapiauthJSON Web Tokenpanulat

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/blcklab-panulat-jwt/health.svg)

```
[![Health](https://phpackages.com/badges/blcklab-panulat-jwt/health.svg)](https://phpackages.com/packages/blcklab-panulat-jwt)
```

###  Alternatives

[auth0/auth0-php

PHP SDK for Auth0 Authentication and Management APIs.

41022.5M98](/packages/auth0-auth0-php)[auth0/login

Auth0 Laravel SDK. Straight-forward and tested methods for implementing authentication, and accessing Auth0's Management API endpoints.

2745.4M3](/packages/auth0-login)[auth0/symfony

Symfony SDK for Auth0 Authentication and Management APIs.

128833.0k](/packages/auth0-symfony)[ellaisys/aws-cognito

Laravel Authentication using AWS Cognito (Web and API)

121269.8k1](/packages/ellaisys-aws-cognito)[auth0/wordpress

WordPress Plugin for Auth0

18226.2k](/packages/auth0-wordpress)[benbjurstrom/cognito-jwt-guard

A laravel auth guard for JSON Web Tokens issued by Amazon AWS Cognito

1113.1k](/packages/benbjurstrom-cognito-jwt-guard)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
