2017 © Pedro Pelรกez
 

library hotjot

No-frills JWT library

image

ignislabs/hotjot

No-frills JWT library

  • Wednesday, November 22, 2017
  • by Cosmicist
  • Repository
  • 1 Watchers
  • 1 Stars
  • 5 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 0 Forks
  • 0 Open issues
  • 3 Versions
  • 0 % Grown

The README.md

HotJot

Build Status Version License, (*1)

No-frills JWT & JWS library., (*2)

Installation

Install with composer:, (*3)

$ composer require ignislabs/hotjot

Requirements

  • PHP >= 7.1
  • OpenSSL extension
  • JSON extension

Usage

Creating, verifying and validating tokens is really simple, let's take a quick look at these operations before we dive to each component in more detail., (*4)

Create a token:, (*5)

$token = $factory->create($claims, $headers);

Verify a token:, (*6)

$signer->verify($token);

Validate a token:, (*7)

$validator->validate($token);

Let's take a look at the signers first, as these are the most important part of the library. You need a signer to create signed tokens and verify them., (*8)

Signers

You can choose between HMAC, RSA or None signers., (*9)

HMAC Signers

HMAC are the simplest ones. It's a symmetric algorithm, which means you only have a single private encryption key. You should try to make this as cryptographically secure and random as possible., (*10)

You have 3 different options: HS256, HS384, and HS512. All three require only an encryption key as a constructor parameter., (*11)

$signer = new \IgnisLabs\HotJot\Signer\HMAC\HS512('encryption key');

RSA Signers

RSA is asymmetric, which means you'll need to create a key pair:, (*12)

# create a strong, password protected private key
$ openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -outform PEM -out private.pem -pass stdin

# get public key
$ openssl rsa -pubout -in private.pem -out public.pem

If you don't want to generate a password protected key, just omit -pass stdin., (*13)

You can, if you need/want to, make your public key publicly available so anyone can use it to verify if the token is really signed by you ., (*14)

Again, you have 3 different options: RS256, RS384, and RS512. All three require both private and public keys, and the passphrase if your private key is protected., (*15)

$privateKey = file_get_contents('/path/to/private.pem');
$publicKey = file_get_contents('/path/to/public.pem');

$signer = new \IgnisLabs\HotJot\Signer\RSA\RS512($privateKey, $publicKey, 'key passphrase (if any)');

The private key is used for signing and the public key for verification., (*16)

None Signer

Using the None signer will result in an unsecured token with no signature, and verification with this signer will always fail, as unsecured tokens are not signed., (*17)

Warning! Even though you technically can create unsecured tokens, you should be really careful and know very well what you're doing., (*18)

This signer doesn't require any parameters, as it can't sign or verify. It will always return an empty string as a signature, and verification will always fail., (*19)

$signer = new \IgnisLabs\HotJot\Signer\None;

Token Creation

Now that you know about signers, let's see how can you create tokens., (*20)

To create tokens you'll need the Factory and a Signer, and you'll get a Token object with a few handy methods., (*21)

Creating Secured Tokens

To crete secured tokens, use any signer except None., (*22)

$signer = new \IgnisLabs\HotJot\Signer\HMAC\HS512('encryption key');
$factory = new \IgnisLabs\HotJot\Factory($signer);

$token = $factory->create([
    'iss' => 'http://api.example.com',
    'aud' => 'http://www.example.com',
    'jti' => bin2hex(random_bytes(16)),
    'exp' => (new DateTime('+10 days'))->getTimestamp(),
    // etc...
]);

$token->getHeader('alg'); // -> 'HS512'
$token->getClaim('iss'); // -> 'http://api.example.com'
$token->getClaim('exp'); // -> DateTime object

As you can see, exp returns a DateTime object, and so will iat and nbf., (*23)

If you need to use a different signer for some reason, you can do it like this:, (*24)

$newFactory = $factory->setSigner($anotherSigner);

The factory is immutable, so when you do this, the current factory instance is not modified, instead a new instance is returned with the new signer., (*25)

This is useful when you want to temporarily change the signature for a special use case., (*26)

Creating Unsecured Tokens

To create unsecured tokens you need to use the None signer., (*27)

Warning! Even though you technically can create unsecured tokens, you should be really careful and know very well what you're doing., (*28)

$signer = new \IgnisLabs\HotJot\Signer\None;
$factory = new \IgnisLabs\HotJot\Factory($signer);

$token = $factory->create([
    'iss' => 'http://api.example.com',
    'aud' => 'http://www.example.com',
    'jti' => bin2hex(random_bytes(16)),
    'exp' => (new DateTime('+10 days'))->getTimestamp(),
    // etc...
]);

$token->getClaim('alg'); // -> 'none'
$token->getSignature(); // -> null

Parsing

You can parse encoded token strings with the parser. How you obtain the encoded token is out of the scope of the library (authorization header, query parameter, etc)., (*29)

When you parse an encoded token, you'll get back a Token object, same one as with the Factory., (*30)

$parser = new \IgnisLabs\HotJot\Parser;
$token = $parser->parse($encodedTokenString);

The parser does not verify or validate the token, as long as it can parse it and it's rfc-compliant, the parser will succeed and return the token object. You'll need to use a Signer and the Validator to verify and validate the token., (*31)

If the parser does fail it will throw an InvalidTokenException with the appropriate message., (*32)

Signature Verification

This is a critical step when receiving tokens from the outside world., (*33)

This library does not automatically set any algorithm based on the alg header, and you shouldn't do this either. By following this simple rule you will avoid [known vulnerabilities][1]., (*34)

This library makes it easy not to fall for this exploits by simply requiring you to instantiate the desired signer yourself, and making a hard association between the keys and the signers by passing keys on instantiation rather than on verification, leaving less room for error., (*35)

All signers will first check the token's alg header and check if it matches the signer's algorithm. If the algorithms don't match it will throw a SignatureVerificationException exception., (*36)

$signer = new \IgnisLabs\HotJot\Signer\RSA\RS512($privateKey, $publicKey, 'passphrase');
$signer->verify($token); // -> boolean โ€” $token most likely obtained through the parser

Validation

Once you have a verified token, you can start to validate it using the Validator., (*37)

The Validator is a really simple class that takes a bunch of token validators and uses them to validate a token. The validators don't return eny values, but throw exceptions on failure., (*38)

This library already comes with some useful ones, but you can add as many as you need., (*39)

use IgnisLabs\HotJot\Validators as ๐Ÿ•ต;

$validator = new \IgnisLabs\HotJot\Validator(
    new ๐Ÿ•ต\IssuedAtValidator, // fails if token used before `iat`
    new ๐Ÿ•ต\NotBeforeValidator, // fails if token used before `nbf`
    new ๐Ÿ•ต\ExpiresAtValidator // fails if token is used after `exp`
);

$validator->validate($token);

If you want to make any of these validators be required, you can instantiate them like this:, (*40)

use IgnisLabs\HotJot\Validators as ๐Ÿ•ต;

$validator = new \IgnisLabs\HotJot\Validator(
    new ๐Ÿ•ต\IssuedAtValidator(true),
    new ๐Ÿ•ต\NotBeforeValidator(true),
    new ๐Ÿ•ต\ExpiresAtValidator(true)
);

$validator->validate($token);

You can create your own validators, you just need them to implement the IgnisLabs\HotJot\Contracts\TokenValidator contract. You also have the \IgnisLabs\HotJot\Validators\ClaimRequiredTrait to save you some time when creating required validators., (*41)

Algorithms

:heavy_check_mark: none
:heavy_check_mark: HS256
:heavy_check_mark: HS384
:heavy_check_mark: HS512
:heavy_check_mark: RS256
:heavy_check_mark: RS384
:heavy_check_mark: RS512
:black_square_button: ES256
:black_square_button: ES384
:black_square_button: ES512, (*42)

The Versions

22/11 2017

dev-master

9999999-dev

No-frills JWT library

  Sources   Download

MIT

The Requires

  • php >=7.1
  • ext-json *
  • ext-openssl *

 

The Development Requires

22/11 2017

1.0.0

1.0.0.0

No-frills JWT library

  Sources   Download

MIT

The Requires

  • php >=7.1
  • ext-json *
  • ext-openssl *

 

The Development Requires

25/10 2017

0.1.0

0.1.0.0

No-frills JWT library

  Sources   Download

MIT

The Requires

  • php >=7.1
  • ext-json *
  • ext-openssl *

 

The Development Requires