PHPackages                             miladrahimi/php-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. miladrahimi/php-jwt

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

miladrahimi/php-jwt
===================

A PHP implementation of JWT (JSON Web Token) generator, parser, verifier, and validator

v3.2.3(1y ago)70263.2k↓17.4%9[1 issues](https://github.com/miladrahimi/php-jwt/issues)2MITPHPPHP &gt;=7.4CI failing

Since Jun 2Pushed 1y ago4 watchersCompare

[ Source](https://github.com/miladrahimi/php-jwt)[ Packagist](https://packagist.org/packages/miladrahimi/php-jwt)[ Docs](https://github.com/miladrahimi/php-jwt)[ Fund](https://miladrahimi.com/pay.html)[ Fund](https://www.paypal.com/paypalme/realmiladrahimi)[ RSS](/packages/miladrahimi-php-jwt/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (1)Versions (23)Used By (2)

[![Latest Stable Version](https://camo.githubusercontent.com/57ffdeb423f620daa674a5602b3989f3e3e124312ac9f3d71cdda105054d3cfb/68747470733a2f2f706f7365722e707567782e6f72672f6d696c6164726168696d692f7068702d6a77742f762f737461626c65)](https://packagist.org/packages/miladrahimi/php-jwt)[![Total Downloads](https://camo.githubusercontent.com/54b84bea9f3028c0b079b3903f6365d4f9de050ca3ed7154be5d045bacfcdd33/68747470733a2f2f706f7365722e707567782e6f72672f6d696c6164726168696d692f7068702d6a77742f646f776e6c6f616473)](https://packagist.org/packages/miladrahimi/php-jwt)[![Build](https://github.com/miladrahimi/php-jwt/actions/workflows/ci.yml/badge.svg)](https://github.com/miladrahimi/php-jwt/actions/workflows/ci.yml)[![codecov](https://camo.githubusercontent.com/76da2ae88ed98c91e688b624a51f02d51710cd4864f80f5365d1a18ef7191567/68747470733a2f2f636f6465636f762e696f2f67682f6d696c6164726168696d692f7068702d6a77742f67726170682f62616467652e7376673f746f6b656e3d4b637472595577654664)](https://codecov.io/gh/miladrahimi/php-jwt)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/ba0fd966b42029724cfca7d272003fec2c52c51b6e5a4c9afb78b4c9818ab5ab/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f6d696c6164726168696d692f7068702d6a77742f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/miladrahimi/php-jwt/?branch=master)[![License](https://camo.githubusercontent.com/d097761a049a13d2b6409fc211bb1f4389dbff439e6fd4067f83c35e8bea3beb/68747470733a2f2f706f7365722e707567782e6f72672f6d696c6164726168696d692f7068702d6a77742f6c6963656e7365)](https://packagist.org/packages/miladrahimi/php-jwt)

PHP-JWT
=======

[](#php-jwt)

PHP-JWT is a PHP package built for encoding (generating), decoding (parsing), verifying, and validating JSON Web Tokens (JWTs). Its design emphasizes a fluent, user-friendly, and object-oriented interface, crafted with performance in mind.

Supported algorithms:

- HMAC: `HS256`, `HS384`, and `HS512`
- RSA: `RS256`, `RS384`, and `RS512`
- ECDSA: `ES256`, `ES256K`, and `RS384`
- EdDSA: `EdDSA`

Supported features:

- Built-in and custom validations
- Multiple key and `kid` header handler

Confirmed by [JWT.io](https://jwt.io).

Documentation
-------------

[](#documentation)

### What is JWT?

[](#what-is-jwt)

If you're not familiar with JWTs, you can refer to the [Wikipedia page](https://en.wikipedia.org/wiki/JSON_Web_Token) or visit [JWT.io](https://jwt.io) for more information.

### Installation

[](#installation)

Include the package in your Composer dependencies using the following command:

```
composer require miladrahimi/php-jwt "3.*"
```

### Quick Start

[](#quick-start)

Here's an example demonstrating how to generate a JWT and parse it using the `HS256` algorithm:

```
use MiladRahimi\Jwt\Generator;
use MiladRahimi\Jwt\Parser;
use MiladRahimi\Jwt\Cryptography\Keys\HmacKey;
use MiladRahimi\Jwt\Cryptography\Algorithms\Hmac\HS256;

// Use HS256 to generate and parse JWTs
$key = new HmacKey('12345678901234567890123456789012');
$signer = new HS256($key);

// Generate a JWT
$generator = new Generator($signer);
$jwt = $generator->generate(['id' => 13, 'is-admin' => true]);

print_r($jwt); // "abc.123.xyz"

// Parse the token
$parser = new Parser($signer);
$claims = $parser->parse($jwt);

print_r($claims); // ['id' => 13, 'is-admin' => true]
```

### HMAC Algorithms

[](#hmac-algorithms)

HMAC algorithms rely on symmetric keys, allowing a single key to encode (sign) and decode (verify) JWTs. The PHP-JWT package supports `HS256`, `HS384`, and `HS512` HMAC algorithms. The example above showcases the utilization of an HMAC algorithm to both sign and verify a JWT.

### RSA Algorithms

[](#rsa-algorithms)

RSA algorithms work with pairs of keys: a private key for signing JWTs and a corresponding public key for verification. This method is useful when the authentication server can't completely trust resource owners. The PHP-JWT package supports `RS256`, `RS384`, and `RS512` RSA algorithms. The example below demonstrates this process.

```
use MiladRahimi\Jwt\Cryptography\Algorithms\Rsa\RS256Signer;
use MiladRahimi\Jwt\Cryptography\Algorithms\Rsa\RS256Verifier;
use MiladRahimi\Jwt\Cryptography\Keys\RsaPrivateKey;
use MiladRahimi\Jwt\Cryptography\Keys\RsaPublicKey;
use MiladRahimi\Jwt\Generator;
use MiladRahimi\Jwt\Parser;

// Generate a token
$privateKey = new RsaPrivateKey('/path/to/private.pem');
$signer = new RS256Signer($privateKey);
$generator = new Generator($signer);
$jwt = $generator->generate(['id' => 13, 'is-admin' => true]);

print_r($jwt); // "abc.123.xyz"

// Parse the token
$publicKey = new RsaPublicKey('/path/to/public.pem');
$verifier = new RS256Verifier($publicKey);
$parser = new Parser($verifier);
$claims = $parser->parse($jwt);

print_r($claims); // ['id' => 13, 'is-admin' => true]
```

You can refer to [this instruction](https://en.wikibooks.org/wiki/Cryptography/Generate_a_keypair_using_OpenSSL) to learn how to generate a pair of RSA keys using OpenSSL.

### ECDSA Algorithms

[](#ecdsa-algorithms)

The ECDSA algorithm, similar to RSA, operates asymmetrically, providing even stronger security measures than RSA. The PHP-JWT package supports `ES256`, `ES256K`, and `RS384` ECDSA algorithms. The example below demonstrates this process.

```
use MiladRahimi\Jwt\Cryptography\Algorithms\Ecdsa\ES384Signer;
use MiladRahimi\Jwt\Cryptography\Algorithms\Ecdsa\ES384Verifier;
use MiladRahimi\Jwt\Cryptography\Keys\EcdsaPrivateKey;
use MiladRahimi\Jwt\Cryptography\Keys\EcdsaPublicKey;
use MiladRahimi\Jwt\Generator;
use MiladRahimi\Jwt\Parser;

// Generate a token
$privateKey = new EcdsaPrivateKey('/path/to/private.pem');
$signer = new ES384Signer($privateKey);
$generator = new Generator($signer);
$jwt = $generator->generate(['id' => 13, 'is-admin' => true]);

print_r($jwt); // "abc.123.xyz"

// Parse the token
$publicKey = new EcdsaPublicKey('/path/to/public.pem');
$verifier = new ES384Verifier($publicKey);
$parser = new Parser($verifier);
$claims = $parser->parse($jwt);

print_r($claims); // ['id' => 13, 'is-admin' => true]
```

EdDSA Algorithm
---------------

[](#eddsa-algorithm)

EdDSA, similar to RSA and ECDSA, is an asymmetric cryptography algorithm and is widely recommended. In order to utilize it, ensure that the `sodium` PHP extension is installed in your environment. The following example demonstrates how to use it.

```
use MiladRahimi\Jwt\Cryptography\Algorithms\Eddsa\EdDsaSigner;
use MiladRahimi\Jwt\Cryptography\Algorithms\Eddsa\EdDsaVerifier;
use MiladRahimi\Jwt\Generator;
use MiladRahimi\Jwt\Parser;

// Generate a token
$privateKey = new EdDsaPrivateKey(base64_decode(file_get_contents('/path/to/ed25519.sec')));
$signer = new EdDsaSigner($privateKey);
$generator = new Generator($signer);
$jwt = $generator->generate(['id' => 13, 'is-admin' => true]);

print_r($jwt); // "abc.123.xyz"

// Parse the token
$publicKey = new EdDsaPublicKey(base64_decode(file_get_contents('/path/to/ed25519.pub')));
$verifier = new EdDsaVerifier($publicKey);
$parser = new Parser($verifier);
$claims = $parser->parse($jwt);

print_r($claims); // ['id' => 13, 'is-admin' => true]
```

Please note that EdDSA keys must be in string format. If they are already base64 encoded, decoding them is necessary before use.

### Validation

[](#validation)

By default, the package validates certain public claims if present (using `DefaultValidator`), and parses the claims. If you have custom claims, you can include their validation rules as well. Check out this example:

```
use MiladRahimi\Jwt\Parser;
use MiladRahimi\Jwt\Cryptography\Algorithms\Hmac\HS256;
use MiladRahimi\Jwt\Exceptions\ValidationException;
use MiladRahimi\Jwt\Validator\Rules\EqualsTo;

$jwt = '...'; // Get the JWT from the user

$signer = new HS256(new HmacKey('12345678901234567890123456789012'));

// Extend the DefaultValidator
$validator = new DefaultValidator();

// The 'is-admin' claim is required, without it or a mismatched rule, validation fails.
$validator->addRequiredRule('is-admin', new EqualsTo(true));

// The 'exp' claim is optional, and the rule will be applicable if it is present.
$validator->addOptionalRule('exp', new NewerThan(time()), false);

// Parse the token
$parser = new Parser($signer, $validator);

try {
    $claims = $parser->parse($jwt);
    print_r($claims); // ['id' => 13, 'is-admin' => true]
} catch (ValidationException $e) {
    // Handle error.
}
```

In the aforementioned example, we extended `DefaultValidator`, which comes with pre-defined Rules for public claims. We strongly suggest extending it for your validation. Note that `DefaultValidator` is a subclass of `BaseValidator`. While you can utilize `BaseValidator` for your validations, opting for this means losing the built-in Rules, requiring you to manually add all the Rules yourself.

#### Rules

[](#rules)

Validators rely on Rules to validate claims, with each Rule specifying acceptable values for a claim. You can access the built-in Rules within the `MiladRahimi\Jwt\Validator\Rules` namespace.

- [ConsistsOf](https://github.com/miladrahimi/php-jwt/blob/master/src/Validator/Rules/ConsistsOf.php)
- [EqualsTo](https://github.com/miladrahimi/php-jwt/blob/master/src/Validator/Rules/EqualsTo.php)
- [GreaterThan](https://github.com/miladrahimi/php-jwt/blob/master/src/Validator/Rules/GreaterThan.php)
- [GreaterThanOrEqualTo](https://github.com/miladrahimi/php-jwt/blob/master/src/Validator/Rules/GreaterThanOrEqualTo.php)
- [IdenticalTo](https://github.com/miladrahimi/php-jwt/blob/master/src/Validator/Rules/IdenticalTo.php)
- [LessThan](https://github.com/miladrahimi/php-jwt/blob/master/src/Validator/Rules/LessThan.php)
- [LessThanOrEqualTo](https://github.com/miladrahimi/php-jwt/blob/master/src/Validator/Rules/LessThanOrEqualTo.php)
- [NewerThan](https://github.com/miladrahimi/php-jwt/blob/master/src/Validator/Rules/NewerThan.php)
- [NewerThanOrSame](https://github.com/miladrahimi/php-jwt/blob/master/src/Validator/Rules/NewerThanOrSame.php)
- [NotEmpty](https://github.com/miladrahimi/php-jwt/blob/master/src/Validator/Rules/NotEmpty.php)
- [NotNull](https://github.com/miladrahimi/php-jwt/blob/master/src/Validator/Rules/NotNull.php)
- [OlderThan](https://github.com/miladrahimi/php-jwt/blob/master/src/Validator/Rules/OlderThan.php)
- [OlderThanOrSame](https://github.com/miladrahimi/php-jwt/blob/master/src/Validator/Rules/OlderThanOrSame.php)

Descriptions for each Rule can be found within their respective class doc blocks.

#### Custom Rules

[](#custom-rules)

If the provided built-in Rules don't fulfill your requirements, you can create custom Rules. To do so, implement the `Rule` interface. For instance, consider the `Even` Rule below, designed to verify whether a given claim represents an even number:

```
use MiladRahimi\Jwt\Exceptions\ValidationException;
use MiladRahimi\Jwt\Validator\Rule;

class Even implements Rule
{
    public function validate(string $name, $value)
    {
        if ($value % 2 != 0) {
            throw new ValidationException("The `$name` must be an even number.");
        }
    }
}
```

### Multiple Keys

[](#multiple-keys)

The `kid` parameter within the JWT header plays a crucial role in managing multiple keys efficiently. By leveraging the "kid" header, you can assign a unique key identifier (kid) to each key that you use to sign JWTs. This enables seamless verification of JWTs by associating them with their respective key identifiers (kid). Check out this example:

```
use MiladRahimi\Jwt\Cryptography\Algorithms\Ecdsa\ES384Signer;
use MiladRahimi\Jwt\Cryptography\Algorithms\Ecdsa\ES384Verifier;
use MiladRahimi\Jwt\Cryptography\Algorithms\Rsa\RS256Signer;
use MiladRahimi\Jwt\Cryptography\Algorithms\Rsa\RS256Verifier;
use MiladRahimi\Jwt\Cryptography\Keys\EcdsaPrivateKey;
use MiladRahimi\Jwt\Cryptography\Keys\EcdsaPublicKey;
use MiladRahimi\Jwt\Cryptography\Keys\RsaPrivateKey;
use MiladRahimi\Jwt\Cryptography\Keys\RsaPublicKey;
use MiladRahimi\Jwt\Generator;
use MiladRahimi\Jwt\Parser;

$privateKey1 = new RsaPrivateKey('/path/to/rsa-private.pem', '', 'key-1');
$publicKey1 = new RsaPublicKey('/path/to/rsa-public.pem', 'key-1');

$privateKey2 = new EcdsaPrivateKey('/path/to/ecdsa384-private.pem', '', 'key-2');
$publicKey2 = new EcdsaPublicKey('/path/to/ecdsa384-public.pem', 'key-2');

// Generate tokens

$signer1 = new RS256Signer($privateKey1);
$generator1 = new Generator($signer1);
$jwt1 = $generator1->generate(['id' => 13, 'is-admin' => true]);
// $jwt1 header: {"alg": "RS256", "typ": "JWT", "kid": "key-1"}

$signer2 = new ES384Signer($privateKey2);
$generator2 = new Generator($signer2);
$jwt2 = $generator2->generate(['id' => 13, 'is-admin' => true]);
// $jwt2 header: {"alg": "ES384", "typ": "JWT", "kid": "key-2"}

// Parse tokens

$verifierFactory = new VerifierFactory([
    new RS256Verifier($publicKey1),
    new ES384Verifier($publicKey2),
]);

$verifier1 = $verifierFactory->getVerifier($jwt1); // instance of RS256Verifier
$parser1 = new Parser($verifier1);
$claims1 = $parser1->parse($jwt1);
print_r($claims1); // ['id' => 13, 'is-admin' => true]

$verifier2 = $verifierFactory->getVerifier($jwt2); // instance of ES384Verifier
$parser2 = new Parser($verifier2);
$claims2 = $parser2->parse($jwt2);
print_r($claims2); // ['id' => 13, 'is-admin' => true]
```

### Error Handling

[](#error-handling)

Here are the exceptions that the package might throw:

- Encoding:
    - [InvalidKeyException](src/Exceptions/InvalidKeyException.php) when the provided key is not valid.
    - [JsonEncodingException](src/Exceptions/JsonEncodingException.php) when cannot convert the provided claims to JSON.
    - [SigningException](src/Exceptions/SigningException.php) when cannot sign the token using the provided signer or key.
- Decoding:
    - [InvalidTokenException](src/Exceptions/InvalidTokenException.php) when the JWT format is not valid (for example, it has no payload).
    - [InvalidSignatureException](src/Exceptions/InvalidSignatureException.php) when the JWT signature is not valid.
    - [JsonDecodingException](src/Exceptions/JsonDecodingException.php) when the JSON extracted from JWT is not valid.
    - [ValidationException](src/Exceptions/ValidationException.php) when at least one of the validation rules fails.
- Finding Verifier:
    - [NoKidException](src/Exceptions/NoKidException.php) when there is no `kid` in the token header.
    - [VerifierNotFoundException](src/Exceptions/VerifierNotFoundException.php) when no key/verifier matches the `kid` in the token header.

All of the exceptions mentioned are subclasses of the [JwtException](src/Exceptions/JwtException.php) exception. By catching `JwtException`, you can handle all these cases collectively instead of catching each one individually.

License
-------

[](#license)

PHP-JWT is initially created by [Milad Rahimi](http://miladrahimi.com)and released under the [MIT License](http://opensource.org/licenses/mit-license.php).

###  Health Score

49

—

FairBetter than 95% of packages

Maintenance40

Moderate activity, may be stable

Popularity48

Moderate usage in the ecosystem

Community19

Small or concentrated contributor base

Maturity73

Established project with proven stability

 Bus Factor1

Top contributor holds 97.8% 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 ~114 days

Recently: every ~99 days

Total

22

Last Release

512d ago

Major Versions

v1.1.5 → v2.0.02019-11-10

v2.x-dev → v3.0.02023-11-16

PHP version history (4 changes)v1.0PHP &gt;=7.0

v2.0.0PHP &gt;=7.1

v2.1.2PHP &gt;=7.1|^8.0

v3.0.0PHP &gt;=7.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/921274b8bb29236d8f94f6c83100a5f751f6394c4c49741e1b92bfbccac0911b?d=identicon)[miladrahimi](/maintainers/miladrahimi)

---

Top Contributors

[![miladrahimi](https://avatars.githubusercontent.com/u/6689295?v=4)](https://github.com/miladrahimi "miladrahimi (131 commits)")[![lavrentiev](https://avatars.githubusercontent.com/u/479593?v=4)](https://github.com/lavrentiev "lavrentiev (2 commits)")[![augustowebd](https://avatars.githubusercontent.com/u/37518?v=4)](https://github.com/augustowebd "augustowebd (1 commits)")

---

Tags

josejson-web-tokenjwtphpphp-jwtjwtvalidatorparsertokenJSON Web Tokenencoderdecoderverifier

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/miladrahimi-php-jwt/health.svg)

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

###  Alternatives

[namshi/jose

JSON Object Signing and Encryption library for PHP.

1.8k99.6M101](/packages/namshi-jose)[tymon/jwt-auth

JSON Web Token Authentication for Laravel and Lumen

11.5k49.1M350](/packages/tymon-jwt-auth)[adhocore/jwt

Ultra lightweight JSON web token (JWT) library for PHP5.5+.

3031.6M15](/packages/adhocore-jwt)[php-open-source-saver/jwt-auth

JSON Web Token Authentication for Laravel and Lumen

8359.8M53](/packages/php-open-source-saver-jwt-auth)[auth0/auth0-php

PHP SDK for Auth0 Authentication and Management APIs.

40820.2M68](/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.0M3](/packages/auth0-login)

PHPackages © 2026

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