PHPackages                             andrewdyer/jwt-auth - 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. andrewdyer/jwt-auth

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

andrewdyer/jwt-auth
===================

A framework-agnostic PHP JWT authentication library for managing tokens, built around contracts for user resolution and claims generation

0.1.4(1mo ago)00MITPHPPHP ^8.3CI passing

Since Mar 31Pushed 3w agoCompare

[ Source](https://github.com/andrewdyer/jwt-auth)[ Packagist](https://packagist.org/packages/andrewdyer/jwt-auth)[ RSS](/packages/andrewdyer-jwt-auth/feed)WikiDiscussions main Synced today

READMEChangelog (5)Dependencies (4)Versions (16)Used By (0)

[![JWT Auth](https://camo.githubusercontent.com/87031903c387b88c32b5d721a73738f7151d0793eb4d1090e3437e8aab54b77a/68747470733a2f2f7075626c69632d6173736574732e616e64726577647965722e726f636b732f696d616765732f636f766572732f6a77742d617574682e706e67)](https://camo.githubusercontent.com/87031903c387b88c32b5d721a73738f7151d0793eb4d1090e3437e8aab54b77a/68747470733a2f2f7075626c69632d6173736574732e616e64726577647965722e726f636b732f696d616765732f636f766572732f6a77742d617574682e706e67)

 [![Latest Stable Version](https://camo.githubusercontent.com/32356a779e32c8cfed7e40f88f7667d4376dd80a1cd8361afa8d95102c21d355/68747470733a2f2f706f7365722e707567782e6f72672f616e64726577647965722f6a77742d617574682f762f737461626c653f7374796c653d666f722d7468652d6261646765)](https://packagist.org/packages/andrewdyer/jwt-auth) [![Total Downloads](https://camo.githubusercontent.com/af85b0ab35dbadbc800d6c55cc3676f0fadf48faeebef68850c582ed3a983202/68747470733a2f2f706f7365722e707567782e6f72672f616e64726577647965722f6a77742d617574682f646f776e6c6f6164733f7374796c653d666f722d7468652d6261646765)](https://packagist.org/packages/andrewdyer/jwt-auth) [![License](https://camo.githubusercontent.com/235dc051f7ec1d35ca5466a1cb80572beb1d2057443628255a8f62041a262260/68747470733a2f2f706f7365722e707567782e6f72672f616e64726577647965722f6a77742d617574682f6c6963656e73653f7374796c653d666f722d7468652d6261646765)](https://packagist.org/packages/andrewdyer/jwt-auth) [![PHP Version Required](https://camo.githubusercontent.com/b065474f4b839f83808eceb3eec1420f66a1545664a760bbbdc6280b7197a11f/68747470733a2f2f706f7365722e707567782e6f72672f616e64726577647965722f6a77742d617574682f726571756972652f7068703f7374796c653d666f722d7468652d6261646765)](https://packagist.org/packages/andrewdyer/jwt-auth)

JWT Auth
========

[](#jwt-auth)

A framework-agnostic PHP JWT authentication library for managing tokens, built around contracts for user resolution and claims generation.

Introduction
------------

[](#introduction)

This library provides a clean, contract-driven approach to JSON Web Token authentication by coordinating token issuance and parsing while delegating token handling, user resolution, and claims generation to user-defined implementations. By relying on simple interfaces, it remains fully framework-agnostic and unopinionated, allowing integration with any authentication system or JWT library.

Prerequisites
-------------

[](#prerequisites)

- **[PHP](https://www.php.net/)**: Version 8.3 or higher is required.
- **[Composer](https://getcomposer.org/)**: Dependency management tool for PHP.

Installation
------------

[](#installation)

```
composer require andrewdyer/jwt-auth
```

Getting Started
---------------

[](#getting-started)

### 1. Implement the JWT subject

[](#1-implement-the-jwt-subject)

Any class that represents an authenticated user or entity must implement `JwtSubjectInterface`. This provides the identifier that will be stored in the token's `sub` claim.

```
use AndrewDyer\JwtAuth\Contracts\JwtSubjectInterface;

class User implements JwtSubjectInterface
{
    public function __construct(private int $id) {}

    public function getJwtIdentifier(): int|string
    {
        return $this->id;
    }
}
```

### 2. Implement the auth provider

[](#2-implement-the-auth-provider)

A class implementing `AuthProviderInterface` must be provided to resolve users by credentials or by ID. `JwtAuth` calls these methods internally during `attempt()` and `authenticate()`.

```
use AndrewDyer\JwtAuth\Contracts\AuthProviderInterface;

class MyAuthProvider implements AuthProviderInterface
{
    public function byCredentials(string $username, string $password): ?JwtSubjectInterface
    {
        // Return a JwtSubjectInterface instance on success, or null on failure
    }

    public function byId(int|string $id): ?JwtSubjectInterface
    {
        // Return a JwtSubjectInterface instance, or null if not found
    }
}
```

### 3. Implement the JWT provider

[](#3-implement-the-jwt-provider)

A class implementing `JwtProviderInterface` handles token encoding and decoding. This is the integration point for a preferred JWT library such as [`firebase/php-jwt`](https://github.com/firebase/php-jwt) or [`lcobucci/jwt`](https://github.com/lcobucci/jwt).

```
use AndrewDyer\JwtAuth\Contracts\JwtProviderInterface;

class MyJwtProvider implements JwtProviderInterface
{
    public function encode(array $claims): string
    {
        // Encode the claims array into a signed token string
    }

    public function decode(string $token): mixed
    {
        // Decode and verify the token; return the payload as an array or object
    }
}
```

### 4. Implement the claims factory

[](#4-implement-the-claims-factory)

A class implementing `ClaimsFactoryInterface` builds the JWT claims for a given user. The `iat`, `nbf`, and `exp` fields accept plain Unix timestamps from `time()`, [Carbon](https://github.com/briannesbitt/Carbon), or any other source.

```
use AndrewDyer\JwtAuth\Claims;
use AndrewDyer\JwtAuth\Contracts\ClaimsFactoryInterface;
use AndrewDyer\JwtAuth\Contracts\JwtSubjectInterface;

class MyClaimsFactory implements ClaimsFactoryInterface
{
    public function forSubject(JwtSubjectInterface $subject): Claims
    {
        $now = time();

        return new Claims(
            iss: 'my-app',
            aud: 'my-api',
            iat: $now,
            nbf: $now,
            exp: $now + 3600,
            jti: bin2hex(random_bytes(16)),
            sub: $subject->getJwtIdentifier(),
        );
    }
}
```

When using Carbon, `Carbon::now()->timestamp` is a drop-in replacement for `time()`.

Usage
-----

[](#usage)

### Create a JwtAuth instance

[](#create-a-jwtauth-instance)

The three dependencies are wired up to create a `JwtAuth` instance:

```
use AndrewDyer\JwtAuth\JwtAuth;

$auth = new JwtAuth(
    authProvider: new MyAuthProvider(),
    jwtProvider: new MyJwtProvider(),
    claimsFactory: new MyClaimsFactory(),
);
```

### Attempt a login

[](#attempt-a-login)

Validates a username and password and returns a signed token. Throws `InvalidCredentialsException` if the credentials are invalid.

```
use AndrewDyer\JwtAuth\Exceptions\InvalidCredentialsException;

try {
    $token = $auth->attempt('user@example.com', 'secret');
} catch (InvalidCredentialsException $e) {
    // Credentials did not match a valid user
}
```

### Authenticate a token

[](#authenticate-a-token)

Decodes a token, verifies it, and returns the corresponding user. Throws `InvalidTokenException` if the token is invalid or the user cannot be found.

```
use AndrewDyer\JwtAuth\Exceptions\InvalidTokenException;

try {
    $user = $auth->authenticate($token);
} catch (InvalidTokenException $e) {
    // Token is invalid or the user no longer exists
}
```

### Parse a token

[](#parse-a-token)

Decodes a token into a `Claims` object without looking up the user.

```
use AndrewDyer\JwtAuth\Exceptions\InvalidTokenException;

try {
    $claims = $auth->parse($token);

    echo $claims->sub; // The subject identifier
    echo $claims->iss; // The issuer
    echo $claims->exp; // Expiry timestamp
} catch (InvalidTokenException $e) {
    // Token could not be decoded
}
```

Claims
------

[](#claims)

The `Claims` class is a read-only value object representing the payload of a JWT. It exposes the standard registered claims as typed public properties:

PropertyTypeDescription`iss``string`Issuer`aud``?string`Audience`iat``int`Issued-at timestamp`nbf``int`Not-before timestamp`exp``int`Expiry timestamp`jti``string`Unique token identifier`sub``int|string`Subject identifier (user ID)`custom``array`Any additional custom claimsA `Claims` instance can be serialized back to an array using `toArray()`, which omits null values:

```
$array = $claims->toArray();
```

A `Claims` instance can also be constructed directly from an array. The claims `iss`, `iat`, `nbf`, `exp`, `jti`, and `sub` are all required; `aud` is optional and defaults to `null` if omitted. All values must match their expected types — throws `InvalidTokenException` if any required claim is missing or any claim has an invalid type:

```
$claims = Claims::fromArray([
    'iss' => 'my-app',
    'aud' => 'my-api',
    'iat' => 1711324800,
    'nbf' => 1711324800,
    'exp' => 1711328400,
    'jti' => 'abc123',
    'sub' => 42,
]);
```

Any keys not in the standard set are captured in the `custom` array.

Exceptions
----------

[](#exceptions)

ExceptionThrown when`InvalidCredentialsException``attempt()` is called and the credentials do not resolve to a valid user`InvalidTokenException`A token cannot be decoded, required claims are missing or have invalid types, or the subject cannot be resolved to a valid userBoth extend `RuntimeException`.

License
-------

[](#license)

Licensed under the [MIT license](https://opensource.org/licenses/MIT) and is free for private or commercial projects.

###  Health Score

38

—

LowBetter than 85% of packages

Maintenance94

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

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

Every ~109 days

Recently: every ~0 days

Total

13

Last Release

40d ago

Major Versions

1.x-dev → 2.0.02024-12-15

PHP version history (3 changes)1.0.0PHP ^7.2.5

2.0.0PHP ^8.2

0.1.0PHP ^8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/666597ea6e46748a89fe8764d1a45b4d0da97daf1bb1e9770ea34ae41f706d08?d=identicon)[andrewdyer](/maintainers/andrewdyer)

---

Top Contributors

[![andrewdyer](https://avatars.githubusercontent.com/u/8114523?v=4)](https://github.com/andrewdyer "andrewdyer (9 commits)")

---

Tags

authenticationframework-agnosticjwtphpsecuritytokensphpjwttokenssecurityAuthenticationframework agnostic

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/andrewdyer-jwt-auth/health.svg)

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

###  Alternatives

[rbdwllr/reallysimplejwt

A really simple library to generate user authentication JSON Web Tokens.

2902.4M22](/packages/rbdwllr-reallysimplejwt)[maicol07/flarum-ext-sso

SSO for Flarum

468.3k](/packages/maicol07-flarum-ext-sso)

PHPackages © 2026

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