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

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

gitsindonesia/php-jwt
=====================

A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Forked from firebase/php-jwt to include patches for version 5.5.1.

v6.11.1(1y ago)0236↓33.3%BSD-3-ClausePHPPHP ^8.0

Since Aug 28Pushed 5mo agoCompare

[ Source](https://github.com/gitsindonesia/php-jwt)[ Packagist](https://packagist.org/packages/gitsindonesia/php-jwt)[ Docs](https://github.com/firebase/php-jwt)[ RSS](/packages/gitsindonesia-php-jwt/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (6)Versions (41)Used By (0)

[![Build Status](https://github.com/gitsindonesia/php-jwt/actions/workflows/tests.yml/badge.svg)](https://github.com/gitsindonesia/php-jwt/actions/workflows/tests.yml/badge.svg)[![Latest Stable Version](https://camo.githubusercontent.com/6b3ba1bbd83b4f547517dc57e30cdaa6df8c0ea4ef2e4fd8b2494e84ac5a67b0/68747470733a2f2f706f7365722e707567782e6f72672f67697473696e646f6e657369612f7068702d6a77742f762f737461626c65)](https://packagist.org/packages/gitsindonesia/php-jwt)[![Total Downloads](https://camo.githubusercontent.com/1b29d4909401e6956373b8f7191ddf2f5d88631ea5860de5772f9cba8f66d5c6/68747470733a2f2f706f7365722e707567782e6f72672f67697473696e646f6e657369612f7068702d6a77742f646f776e6c6f616473)](https://packagist.org/packages/gitsindonesia/php-jwt)[![License](https://camo.githubusercontent.com/eeb1986afae62cbca443eda0c94d7f46c3d1f5d63ee8a2360a5ecc89511fbdfc/68747470733a2f2f706f7365722e707567782e6f72672f67697473696e646f6e657369612f7068702d6a77742f6c6963656e7365)](https://packagist.org/packages/gitsindonesia/php-jwt)

PHP-JWT ( Forked from firebase/php-jwt to include patches for version 5.5.1 )
=============================================================================

[](#php-jwt--forked-from-firebasephp-jwt-to-include-patches-for-version-551-)

Forked from firebase/php-jwt to include patches for version 5.5.1.

A simple library to encode and decode JSON Web Tokens (JWT) in PHP, conforming to [RFC 7519](https://tools.ietf.org/html/rfc7519).

PHP-JWT (GITS Indonesia Patched Version)
========================================

[](#php-jwt-gits-indonesia-patched-version)

### ⚠️ Security Patch for Version 5.5.1

[](#️-security-patch-for-version-551)

This repository is a fork of `firebase/php-jwt` specifically providing a **security-patched version** of the 5.5.1 release.

Why is this Fork Necessary?
---------------------------

[](#why-is-this-fork-necessary)

Many legacy Laravel projects or those utilizing **Laravel Passport (v7 and below)** have dependency constraints where `firebase/php-jwt` is locked to version `^5.0`.

Since official security fixes are primarily released for version `6.x` and above, these projects often remain flagged as **vulnerable** during security audits (e.g., via `composer audit`), yet they cannot upgrade to version 6.x due to strict dependency conflicts with other packages.

**This fork allows you to:**

1. **Fix Vulnerabilities:** Stay secure while remaining on the 5.x version line.
2. **Avoid Dependency Conflicts:** Fully compatible with Laravel Passport or Google API Client that requires `firebase/php-jwt: ~5.0`.
3. **Zero Code Changes:** Uses the original `Firebase\JWT` namespace, meaning no changes are required in your existing application code.

---

Installation ( Patched Version 5.5.1 )
--------------------------------------

[](#installation--patched-version-551-)

Since this package is published on **Packagist**, you can install it directly without additional configuration.

### 1. Install the Patched Version

[](#1-install-the-patched-version)

Run the following command to replace the original library with the GITS patched version:

```
composer require gitsindonesia/php-jwt:5.5.1-p1
```

### 2. Verification

[](#2-verification)

To ensure the original `firebase/php-jwt` has been successfully replaced by this fork, run:

```
composer show firebase/php-jwt
```

The output should indicate that the package is being replaced by `gitsindonesia/php-jwt`.

Technical Details
-----------------

[](#technical-details)

- Base Version: 5.5.1
- Patch Version: 5.5.1-p1
- Namespace: Firebase\\JWT (Identical to original)
- License: BSD-3-Clause (Identical to original)
- Compatibility: Tested with Laravel Passport (v7) and Google API PHP Client.

---

Installation ( Please refer to original firebase/php-jwt documentation )
------------------------------------------------------------------------

[](#installation--please-refer-to-original-firebasephp-jwt-documentation-)

Use composer to manage your dependencies and download PHP-JWT:

```
composer require firebase/php-jwt
```

Optionally, install the `paragonie/sodium_compat` package from composer if your php env does not have libsodium installed:

```
composer require paragonie/sodium_compat
```

Example
-------

[](#example)

```
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$key = 'example_key';
$payload = [
    'iss' => 'http://example.org',
    'aud' => 'http://example.com',
    'iat' => 1356999524,
    'nbf' => 1357000000
];

/**
 * IMPORTANT:
 * You must specify supported algorithms for your application. See
 * https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40
 * for a list of spec-compliant algorithms.
 */
$jwt = JWT::encode($payload, $key, 'HS256');
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
print_r($decoded);

// Pass a stdClass in as the third parameter to get the decoded header values
$headers = new stdClass();
$decoded = JWT::decode($jwt, new Key($key, 'HS256'), $headers);
print_r($headers);

/*
 NOTE: This will now be an object instead of an associative array. To get
 an associative array, you will need to cast it as such:
*/

$decoded_array = (array) $decoded;

/**
 * You can add a leeway to account for when there is a clock skew times between
 * the signing and verifying servers. It is recommended that this leeway should
 * not be bigger than a few minutes.
 *
 * Source: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#nbfDef
 */
JWT::$leeway = 60; // $leeway in seconds
$decoded = JWT::decode($jwt, new Key($key, 'HS256'));
```

Example encode/decode headers
-----------------------------

[](#example-encodedecode-headers)

Decoding the JWT headers without verifying the JWT first is NOT recommended, and is not supported by this library. This is because without verifying the JWT, the header values could have been tampered with. Any value pulled from an unverified header should be treated as if it could be any string sent in from an attacker. If this is something you still want to do in your application for whatever reason, it's possible to decode the header values manually simply by calling `json_decode` and `base64_decode` on the JWT header part:

```
use Firebase\JWT\JWT;

$key = 'example_key';
$payload = [
    'iss' => 'http://example.org',
    'aud' => 'http://example.com',
    'iat' => 1356999524,
    'nbf' => 1357000000
];

$headers = [
    'x-forwarded-for' => 'www.google.com'
];

// Encode headers in the JWT string
$jwt = JWT::encode($payload, $key, 'HS256', null, $headers);

// Decode headers from the JWT string WITHOUT validation
// **IMPORTANT**: This operation is vulnerable to attacks, as the JWT has not yet been verified.
// These headers could be any value sent by an attacker.
list($headersB64, $payloadB64, $sig) = explode('.', $jwt);
$decoded = json_decode(base64_decode($headersB64), true);

print_r($decoded);
```

Example with RS256 (openssl)
----------------------------

[](#example-with-rs256-openssl)

```
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$privateKey =  'example.com',
    'iat' => 1356999524,
    'nbf' => 1357000000
];

$jwt = JWT::encode($payload, $privateKey, 'RS256');
echo "Encode:\n" . print_r($jwt, true) . "\n";

$decoded = JWT::decode($jwt, new Key($publicKey, 'RS256'));

/*
 NOTE: This will now be an object instead of an associative array. To get
 an associative array, you will need to cast it as such:
*/

$decoded_array = (array) $decoded;
echo "Decode:\n" . print_r($decoded_array, true) . "\n";
```

Example with a passphrase
-------------------------

[](#example-with-a-passphrase)

```
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

// Your passphrase
$passphrase = '[YOUR_PASSPHRASE]';

// Your private key file with passphrase
// Can be generated with "ssh-keygen -t rsa -m pem"
$privateKeyFile = '/path/to/key-with-passphrase.pem';

// Create a private key of type "resource"
$privateKey = openssl_pkey_get_private(
    file_get_contents($privateKeyFile),
    $passphrase
);

$payload = [
    'iss' => 'example.org',
    'aud' => 'example.com',
    'iat' => 1356999524,
    'nbf' => 1357000000
];

$jwt = JWT::encode($payload, $privateKey, 'RS256');
echo "Encode:\n" . print_r($jwt, true) . "\n";

// Get public key from the private key, or pull from from a file.
$publicKey = openssl_pkey_get_details($privateKey)['key'];

$decoded = JWT::decode($jwt, new Key($publicKey, 'RS256'));
echo "Decode:\n" . print_r((array) $decoded, true) . "\n";
```

Example with EdDSA (libsodium and Ed25519 signature)
----------------------------------------------------

[](#example-with-eddsa-libsodium-and-ed25519-signature)

```
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

// Public and private keys are expected to be Base64 encoded. The last
// non-empty line is used so that keys can be generated with
// sodium_crypto_sign_keypair(). The secret keys generated by other tools may
// need to be adjusted to match the input expected by libsodium.

$keyPair = sodium_crypto_sign_keypair();

$privateKey = base64_encode(sodium_crypto_sign_secretkey($keyPair));

$publicKey = base64_encode(sodium_crypto_sign_publickey($keyPair));

$payload = [
    'iss' => 'example.org',
    'aud' => 'example.com',
    'iat' => 1356999524,
    'nbf' => 1357000000
];

$jwt = JWT::encode($payload, $privateKey, 'EdDSA');
echo "Encode:\n" . print_r($jwt, true) . "\n";

$decoded = JWT::decode($jwt, new Key($publicKey, 'EdDSA'));
echo "Decode:\n" . print_r((array) $decoded, true) . "\n";
```

Example with multiple keys
--------------------------

[](#example-with-multiple-keys)

```
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

// Example RSA keys from previous example
// $privateKey1 = '...';
// $publicKey1 = '...';

// Example EdDSA keys from previous example
// $privateKey2 = '...';
// $publicKey2 = '...';

$payload = [
    'iss' => 'example.org',
    'aud' => 'example.com',
    'iat' => 1356999524,
    'nbf' => 1357000000
];

$jwt1 = JWT::encode($payload, $privateKey1, 'RS256', 'kid1');
$jwt2 = JWT::encode($payload, $privateKey2, 'EdDSA', 'kid2');
echo "Encode 1:\n" . print_r($jwt1, true) . "\n";
echo "Encode 2:\n" . print_r($jwt2, true) . "\n";

$keys = [
    'kid1' => new Key($publicKey1, 'RS256'),
    'kid2' => new Key($publicKey2, 'EdDSA'),
];

$decoded1 = JWT::decode($jwt1, $keys);
$decoded2 = JWT::decode($jwt2, $keys);

echo "Decode 1:\n" . print_r((array) $decoded1, true) . "\n";
echo "Decode 2:\n" . print_r((array) $decoded2, true) . "\n";
```

Using JWKs
----------

[](#using-jwks)

```
use Firebase\JWT\JWK;
use Firebase\JWT\JWT;

// Set of keys. The "keys" key is required. For example, the JSON response to
// this endpoint: https://www.gstatic.com/iap/verify/public_key-jwk
$jwks = ['keys' => []];

// JWK::parseKeySet($jwks) returns an associative array of **kid** to Firebase\JWT\Key
// objects. Pass this as the second parameter to JWT::decode.
JWT::decode($jwt, JWK::parseKeySet($jwks));
```

Using Cached Key Sets
---------------------

[](#using-cached-key-sets)

The `CachedKeySet` class can be used to fetch and cache JWKS (JSON Web Key Sets) from a public URI. This has the following advantages:

1. The results are cached for performance.
2. If an unrecognized key is requested, the cache is refreshed, to accomodate for key rotation.
3. If rate limiting is enabled, the JWKS URI will not make more than 10 requests a second.

```
use Firebase\JWT\CachedKeySet;
use Firebase\JWT\JWT;

// The URI for the JWKS you wish to cache the results from
$jwksUri = 'https://www.gstatic.com/iap/verify/public_key-jwk';

// Create an HTTP client (can be any PSR-7 compatible HTTP client)
$httpClient = new GuzzleHttp\Client();

// Create an HTTP request factory (can be any PSR-17 compatible HTTP request factory)
$httpFactory = new GuzzleHttp\Psr\HttpFactory();

// Create a cache item pool (can be any PSR-6 compatible cache item pool)
$cacheItemPool = Phpfastcache\CacheManager::getInstance('files');

$keySet = new CachedKeySet(
    $jwksUri,
    $httpClient,
    $httpFactory,
    $cacheItemPool,
    null, // $expiresAfter int seconds to set the JWKS to expire
    true  // $rateLimit    true to enable rate limit of 10 RPS on lookup of invalid keys
);

$jwt = 'eyJhbGci...'; // Some JWT signed by a key from the $jwkUri above
$decoded = JWT::decode($jwt, $keySet);
```

Miscellaneous
-------------

[](#miscellaneous)

#### Exception Handling

[](#exception-handling)

When a call to `JWT::decode` is invalid, it will throw one of the following exceptions:

```
use Firebase\JWT\JWT;
use Firebase\JWT\SignatureInvalidException;
use Firebase\JWT\BeforeValidException;
use Firebase\JWT\ExpiredException;
use DomainException;
use InvalidArgumentException;
use UnexpectedValueException;

try {
    $decoded = JWT::decode($jwt, $keys);
} catch (InvalidArgumentException $e) {
    // provided key/key-array is empty or malformed.
} catch (DomainException $e) {
    // provided algorithm is unsupported OR
    // provided key is invalid OR
    // unknown error thrown in openSSL or libsodium OR
    // libsodium is required but not available.
} catch (SignatureInvalidException $e) {
    // provided JWT signature verification failed.
} catch (BeforeValidException $e) {
    // provided JWT is trying to be used before "nbf" claim OR
    // provided JWT is trying to be used before "iat" claim.
} catch (ExpiredException $e) {
    // provided JWT is trying to be used after "exp" claim.
} catch (UnexpectedValueException $e) {
    // provided JWT is malformed OR
    // provided JWT is missing an algorithm / using an unsupported algorithm OR
    // provided JWT algorithm does not match provided key OR
    // provided key ID in key/key-array is empty or invalid.
}
```

All exceptions in the `Firebase\JWT` namespace extend `UnexpectedValueException`, and can be simplified like this:

```
use Firebase\JWT\JWT;
use UnexpectedValueException;
try {
    $decoded = JWT::decode($jwt, $keys);
} catch (LogicException $e) {
    // errors having to do with environmental setup or malformed JWT Keys
} catch (UnexpectedValueException $e) {
    // errors having to do with JWT signature and claims
}
```

#### Casting to array

[](#casting-to-array)

The return value of `JWT::decode` is the generic PHP object `stdClass`. If you'd like to handle with arrays instead, you can do the following:

```
// return type is stdClass
$decoded = JWT::decode($jwt, $keys);

// cast to array
$decoded = json_decode(json_encode($decoded), true);
```

Tests
-----

[](#tests)

Run the tests using phpunit:

```
$ pear install PHPUnit
$ phpunit --configuration phpunit.xml.dist
PHPUnit 3.7.10 by Sebastian Bergmann.
.....
Time: 0 seconds, Memory: 2.50Mb
OK (5 tests, 5 assertions)
```

New Lines in private keys
-------------------------

[](#new-lines-in-private-keys)

If your private key contains `\n` characters, be sure to wrap it in double quotes `""`and not single quotes `''` in order to properly interpret the escaped characters.

License
-------

[](#license)

[3-Clause BSD](http://opensource.org/licenses/BSD-3-Clause).

###  Health Score

46

—

FairBetter than 93% of packages

Maintenance61

Regular maintenance activity

Popularity14

Limited adoption so far

Community19

Small or concentrated contributor base

Maturity80

Battle-tested with a long release history

 Bus Factor2

2 contributors hold 50%+ of commits

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 ~121 days

Recently: every ~143 days

Total

35

Last Release

155d ago

Major Versions

1.0.0 → 2.0.02015-04-01

v2.2.0 → v3.0.02015-07-22

v3.0.0 → v4.0.02016-07-18

v4.0.0 → v5.0.02017-06-27

v5.5.1 → v6.0.02022-01-24

PHP version history (5 changes)1.0.0PHP &gt;=5.2.0

v3.0.0PHP &gt;=5.3.0

v6.1.0PHP ^7.1||^8.0

v6.5.0PHP ^7.4||^8.0

v6.10.1PHP ^8.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/59602236?v=4)[MuhamadAdrian](/maintainers/MuhamadAdrian)[@MuhamadAdrian](https://github.com/MuhamadAdrian)

---

Top Contributors

[![bshaffer](https://avatars.githubusercontent.com/u/103941?v=4)](https://github.com/bshaffer "bshaffer (76 commits)")[![robertdimarco](https://avatars.githubusercontent.com/u/136118?v=4)](https://github.com/robertdimarco "robertdimarco (35 commits)")[![release-please[bot]](https://avatars.githubusercontent.com/in/40688?v=4)](https://github.com/release-please[bot] "release-please[bot] (14 commits)")[![anantn](https://avatars.githubusercontent.com/u/37190?v=4)](https://github.com/anantn "anantn (13 commits)")[![mcocaro](https://avatars.githubusercontent.com/u/2057974?v=4)](https://github.com/mcocaro "mcocaro (6 commits)")[![phansys](https://avatars.githubusercontent.com/u/1231441?v=4)](https://github.com/phansys "phansys (6 commits)")[![jlesueur](https://avatars.githubusercontent.com/u/944916?v=4)](https://github.com/jlesueur "jlesueur (5 commits)")[![sarciszewski](https://avatars.githubusercontent.com/u/3710836?v=4)](https://github.com/sarciszewski "sarciszewski (5 commits)")[![MuhamadAdrian](https://avatars.githubusercontent.com/u/59602236?v=4)](https://github.com/MuhamadAdrian "MuhamadAdrian (4 commits)")[![sjones608](https://avatars.githubusercontent.com/u/9216115?v=4)](https://github.com/sjones608 "sjones608 (3 commits)")[![Krisell](https://avatars.githubusercontent.com/u/25909128?v=4)](https://github.com/Krisell "Krisell (3 commits)")[![4026](https://avatars.githubusercontent.com/u/7915060?v=4)](https://github.com/4026 "4026 (2 commits)")[![ajupazhamayil](https://avatars.githubusercontent.com/u/14087896?v=4)](https://github.com/ajupazhamayil "ajupazhamayil (2 commits)")[![akeeman](https://avatars.githubusercontent.com/u/12628547?v=4)](https://github.com/akeeman "akeeman (2 commits)")[![croensch](https://avatars.githubusercontent.com/u/903943?v=4)](https://github.com/croensch "croensch (2 commits)")[![josephmcdermott](https://avatars.githubusercontent.com/u/6955944?v=4)](https://github.com/josephmcdermott "josephmcdermott (2 commits)")[![peter279k](https://avatars.githubusercontent.com/u/9021747?v=4)](https://github.com/peter279k "peter279k (2 commits)")[![phil-davis](https://avatars.githubusercontent.com/u/1535615?v=4)](https://github.com/phil-davis "phil-davis (2 commits)")[![stampycode](https://avatars.githubusercontent.com/u/5627756?v=4)](https://github.com/stampycode "stampycode (2 commits)")[![vishwarajanand](https://avatars.githubusercontent.com/u/7369612?v=4)](https://github.com/vishwarajanand "vishwarajanand (2 commits)")

---

Tags

phpjwt

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[griffinledingham/php-apple-signin

A simple library to decode and parse Apple Sign In client tokens.

2011.9M1](/packages/griffinledingham-php-apple-signin)[hyperf-ext/jwt

The Hyperf JWT package.

53134.9k2](/packages/hyperf-ext-jwt)[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)
