This package is abandoned and no longer maintained. The author suggests using the firebase/php-jwt package instead.

JSON Object Signing and Encryption library for PHP.

v1.0.0 2015-12-09 17:51 UTC

This package is auto-updated.

Last update: 2020-10-28 14:19:49 UTC


README

Build Status Scrutinizer Code Quality Code Coverage SensioLabs Insight StyleCI Latest Stable Version License

Provides a lightweight implementation of the JWS (JSON Web Signature) specification. This library is a fork of namshi/jose.

Requirements

  1. PHP 5.4.8+ (tested on 5.4, 5.5, 5.6, 7 and HHVM)
  2. (Optional) OpenSSL extension (when using RSA/ECDSA signers)
  3. (Optional) symfony/polyfill-php56 library (when HMAC signers in PHP versions less than 5.6)

Installation

composer require zenstruck/jwt

When using an HMAC signer in PHP versions less than 5.6

composer require symfony/polyfill-php56

Basic Usage

  1. Create, encode and send a token to the user:

    use Zenstruck\JWT\Token;
    use Zenstruck\JWT\Signer\HMAC\HS256;
    
    // create the token
    $token = new Token([
        'username' => 'kevin', // custom claim
        'iss' => 'zenstruck', // set issuer
        'exp' => time() + 86400, // set expiry claim to 1 day from now
    ]);
    
    // can access claims
    $token->get('username'); // kevin
    $token->get('non-existant'); // null
    
    // sign the token
    $token->sign(new HS256(), 'my secret key');
    
    $encodedTokenForUser = (string) $token;
    
    // ...pass to user
  2. Fetch encoded token from user, decode, verify, validate and access custom claims

    use Zenstruck\JWT\Token;
    use Zenstruck\JWT\Signer\HMAC\HS256;
    use Zenstuck\JWT\Validator\ExpiresAtValidator;
    use Zenstuck\JWT\Validator\IssuerValidator;
    use Zenstruck\JWT\Exception\MalformedToken;
    use Zenstruck\JWT\Exception\UnverifiedToken;
    use Zenstruck\JWT\Exception\Validation\ExpiredToken;
    use Zenstruck\JWT\Exception\ValidationFailed;
    
    $encodedTokenFromUser = // ...fetched from user
    
    try {
        $decodedToken = Token::fromString($encodedTokenFromUser);
    } catch (MalformedToken $e) {
        // token is not correctly formed
    }
    
    // at this point $decodedToken is a JWT but is not yet verified or validated
    
    try {
        $decodedToken->verify(new HS256(), 'my secret key');
    } catch (UnverifiedToken $e) {
        // token could not be verified
    }
    
    try {
        $decodedToken->validate(new ExpiresAtValidator());
        $decodedToken->validate(new IssuerValidator('zenstruck'));
    } catch (ExpiredToken $e) {
        // the token has expired
    } catch (ValidationFailed $e) {
        // token is invalid - in this case, the issuer does not match
    }
    
    // can access claims
    $token->get('username'); // kevin
    $token->get('non-existant'); // null

Token Builder

use Zenstruck\JWT\TokenBuilder;

$token = (new TokenBuilder())
    ->issuer('kevin')
    ->subject('zenstruck\jwt')
    ->audience('php community')
    ->expiresAt(new \DateTime('+1 day'))
    ->notBefore(new \DateTime('+1 hour'))
    ->issuedAt() // can pass \DateTime object - uses current time by default
    ->id('foo')
    ->set('foo', 'bar') // set custom claims
    ->create(); // instance of Zenstruck\JWT\Token

Signers

HMAC

These signers require an identical key string to be used for signing and validating.

Algorithm Signer Class
HS256 Zenstruck\JWT\Signer\HMAC\HS256
HS384 Zenstruck\JWT\Signer\HMAC\HS384
HS512 Zenstruck\JWT\Signer\HMAC\HS512

Usage

$token = // ... instance of Zenstruck\JWT\Token
$signer = // an instance of one of the classes in the table above

$token->sign($signer, 'my secret key');
$token->verify($signer, 'my secret key'); // verified
$token->verify($signer, 'invalid secret key'); // unverified - exception thrown

RSA/ECDSA (OpenSSL)

These signers require a private key for signing and a public key for verifying.

  • PrivateKey: a string (key contents or filename), resource or instance of Zenstruck\JWT\Signer\OpenSSL\PrivateKey
  • PublicKey: a string (key contents or filename), resource or instance of Zenstruck\JWT\Signer\OpenSSL\PublicKey
  • Keychain: instance of Zenstruck\JWT\Signer\OpenSSL\Keychain contains both a public and private key. Can be passed as the key to both Signer::sign() and Signer::verify().
Algorithm Signer Class
RS256 Zenstruck\JWT\Signer\OpenSSL\RSA\RS256
RS384 Zenstruck\JWT\Signer\OpenSSL\RSA\RS384
RS512 Zenstruck\JWT\Signer\OpenSSL\RSA\RS512
ES256 Zenstruck\JWT\Signer\OpenSSL\ECDSA\ES256
ES384 Zenstruck\JWT\Signer\OpenSSL\ECDSA\ES384
ES512 Zenstruck\JWT\Signer\OpenSSL\ECDSA\ES512

Usage

$token = // ... instance of Zenstruck\JWT\Token
$signer = // an instance of one of the classes in the table above
$privateKey = // can be string, resource, filename, instance of Zenstruck\JWT\Signer\OpenSSL\PrivateKey, instance of Zenstruck\JWT\Signer\OpenSSL\Keychain
$publicKey = // can be string, resource, filename, instance of Zenstruck\JWT\Signer\OpenSSL\PublicKey, instance of Zenstruck\JWT\Signer\OpenSSL\Keychain

$token->sign($signer, $privateKey);
$token->verify($signer, $publicKey); // verified
$token->verify($signer, '/path/to/unmatched/public/key'); // unverified - exception thrown
Keychain

A keychain contains both a public and private key. When passed a keychain as the key, the signer uses the proper key for the operation.

use Zenstruck\JWT\Signer\OpenSSL\Keychain;

$token = // ... instance of Zenstruck\JWT\Token
$signer = // an instance of one of the classes in the table above
$privateKey = // can be string, resource, filename, instance of Zenstruck\JWT\Signer\OpenSSL\PrivateKey
$publicKey = // can be string, resource, filename, instance of Zenstruck\JWT\Signer\OpenSSL\PublicKey

$keychain = new Keychain($publicKey, $privateKey, 'my passphrase');

$token->sign($signer, $keychain);
$token->verify($signer, $keychain); // verified

Validation

Validator Description
Zenstruck\JWT\Validator\IssuerValidator Ensures iss claim exists and matches expected value
Zenstruck\JWT\Validator\SubjectValidator Ensures sub claim exists and matches expected value
Zenstruck\JWT\Validator\AudienceValidator Ensures aud claim exists and matches expected value
Zenstruck\JWT\Validator\ExpiresAtValidator Ensures exp claim exists is not greater than expected time
Zenstruck\JWT\Validator\NotBeforeValidator Ensures nbf claim exists is not less than expected time
Zenstruck\JWT\Validator\IssuedAtValidator Ensures iat claim exists and matches expected value
Zenstruck\JWT\Validator\IdAtValidator Ensures jti claim exists and matches expected value
Zenstruck\JWT\Validator\ChainValidator Combines any of the above validators together

Usage

use Zenstruck\JWT\Validator\IssuerValidator;
use Zenstruck\JWT\Validator\AudienceValidator;
use Zenstruck\JWT\Validator\ChainValidator;

$token = // ... instance of Zenstruck\JWT\Token
$validator = new ChainValidator([new IssuerValidator(), new AudienceValidator()]);

try {
    $token->validate($validator);
} catch (ValidationFailed $e) {
    $reason = $e->getMessage();
}

ValidatorBuilder

$validator = (new ValidatorBuilder())
    ->issuer('kevin')
    ->subject('zenstruck\jwt')
    ->audience('php community')
    ->expiresAt()
    ->notBefore()
    ->issuedAt(time())
    ->id('foo')
    ->create(); // instance of Zenstruck\JWT\Validator\ChainValidator