This library implements a series of standards related with JSON Web Token and is used by others Re: Message libraries and services like remessage/client
and API server.
You will need Composer to install. Run this command:
composer require remessage/json-web-token
All tokens and services uses algorithms to sign, verify, encrypt and decrypt the token data. Each algorithm MUST implement RM\Standard\Jwt\Algorithm\AlgorithmInterface
.
At this moment, we provide only HMAC-based algorithms:
RM\Standard\Jwt\Algorithm\Signature\HMAC\HS256
for HMAC with SHA-256RM\Standard\Jwt\Algorithm\Signature\HMAC\HS512
for HMAC with SHA-512RM\Standard\Jwt\Algorithm\Signature\HMAC\HS3256
for HMAC with SHA3-256 (or Keccak256)RM\Standard\Jwt\Algorithm\Signature\HMAC\HS3512
for HMAC with SHA3-512 (or Keccak512)
Also, you can implement your own algorithm. You need implement the RM\Standard\Jwt\Algorithm\AlgorithmInterface
interface.
Each key must implement the RM\Standard\Jwt\Key\Factory\KeyInterface
interface.
At the moment, we provide support for:
- Octet key
- RSA keys (PSS and PKCS1) (only signing)
Also, you can implement your own key. You need implement the RM\Standard\Jwt\Key\Factory\KeyFactoryInterface
interface to create your key from array. If your key contains a property that is not implemented in this library, then you also need to implement the RM\Standard\Jwt\Key\Parameter\KeyParameterInterface
interface and use RM\Standard\Jwt\Key\Parameter\Factory\ParameterFactory
with your key parameter class.
To create new token you can use the RM\Standard\Jwt\Signature\SignatureToken
class. The class constructor have 3 arguments: header parameters, payload claims and signature. The header parameters must include the algorithm parameter. Other arguments is optional.
Example:
<?php
use RM\Standard\Jwt\Algorithm\Signature\HMAC\HS3256;
use RM\Standard\Jwt\Property\Header\Algorithm;
use RM\Standard\Jwt\Signature\SignatureToken;
$algorithm = new HS3256();
$token = new SignatureToken([Algorithm::fromAlgorithm($algorithm)]);
Via secondary constructor:
<?php
use RM\Standard\Jwt\Algorithm\Signature\HMAC\HS3256;
use RM\Standard\Jwt\Signature\SignatureToken;
$token = SignatureToken::createWithAlgorithm(new HS3256());
The token has parameters called properties, these are important sensitive data that are needed for authorization and verification. They are separated respectively in the header and in the payload of the token. Header parameters contains the common token data: the signing or encryption algorithm and the type of token. Payload claims contain the data necessary for verification: the token sign/encrypt time, the action time, who signed and for whom. The payload can also include business logic data like permissions or something else.
Header parameters defined in the RM\Standard\Jwt\Property\Header\
namespace. Payload claims defined in the RM\Standard\Jwt\Property\Payload\
namespace.
You can use custom properties. To create your custom property you need implement one of these interfaces:
RM\Standard\Jwt\Property\Header\HeaderParameterInterface
to create custom header parameterRM\Standard\Jwt\Property\Payload\ClaimInterface
to create custom claim
According to the standard, property names must be concise enough. We use 3-character names, but there are no restrictions.
Serialization of tokens provided by some services implemented the RM\Standard\Jwt\Serializer\SerializerInterface
interface.
Example:
<?php
use RM\Standard\Jwt\Serializer\SignatureCompactSerializer;
use RM\Standard\Jwt\Signature\SignatureToken;
// serialized token
// {"alg": "HS256","typ": "JWT"} . {"sub": "1234567890","name": "John Doe","iat": 1516239022} . signature
$rawToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
$serializer = new SignatureCompactSerializer();
// result is a SignatureToken object
// serializer DO NOT validate token
$token = $serializer->deserialize($rawToken);
// will return true
var_dump($rawToken === $token->toString($serializer));
To sign the token you should use the RM\Standard\Jwt\Signature\Signer
. Signer only depends on the serializer, but the default is RM\Standard\Jwt\Serializer\SignatureCompactSerializer
.
Serializer is necessary for the service to sign the token, since the signature is the header and the payload signed by the key.
Also, you can use decorators for Signer to provide some token handling:
RM\Standard\Jwt\Signature\GeneratedSigner
provides ability to generate token property before signingRM\Standard\Jwt\Signature\EventfulSigner
creates eventsRM\Standard\Jwt\Signature\LoggableSigner
allows collecting logs about the signing process
Example:
<?php
use Laminas\Math\Rand;
use ParagonIE\ConstantTime\Base64UrlSafe;
use RM\Standard\Jwt\Algorithm\Signature\HMAC\HS3256;
use RM\Standard\Jwt\Key\Key;
use RM\Standard\Jwt\Key\Parameter\Type;
use RM\Standard\Jwt\Key\Parameter\Value;
use RM\Standard\Jwt\Signature\SignatureToken;
use RM\Standard\Jwt\Signature\Signer;
// some algorithm
$algorithm = new HS3256();
$token = SignatureToken::createWithAlgorithm($algorithm);
// generate random octet key for example
$value = Base64UrlSafe::encode(Rand::getBytes(64));
$key = new Key(
[
new Type(Type::OCTET),
new Value($value),
]
);
$signer = new Signer();
// method returns new token object with signature
$signedToken = $signer->sign($token, $algorithm, $key);
// will return something like this:
// eyJhbGciOiJIUzMyNTYiLCJ0eXAiOiJKV1QifQ.W10.KDa2nZVCuX1LldcMJZz2wp_QifjN7sNHCFLtGDAWF9s
echo $signedToken;
This library implements only the necessary minimum for the correct operation of the service platform.