---
title: "Security - JSON Web Tokens (JWT)"
version: "5.13"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.phalcon.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Security - JSON Web Tokens (JWT)

## Overview

:::info[NOTE]
Currently only HMAC-based (symmetric) signers are supported.
:::

`Phalcon\Encryption\Security\JWT` contains components to issue, parse, and validate JSON Web Tokens as described
in [RFC 7519][rfc-7519].

These components are:

- Builder ([Phalcon\Encryption\Security\JWT\Builder][security-jwt-builder])
- Parser ([Phalcon\Encryption\Security\JWT\Token\Parser][security-jwt-token-parser])
- Validator ([Phalcon\Encryption\Security\JWT\Validator][security-jwt-validator])

:::warning[WARNING]
For the examples below, we have split the output into different lines for readability
:::

An example of using the component is:

```php
<?php

use Phalcon\Encryption\Security\JWT\Builder;
use Phalcon\Encryption\Security\JWT\Signer\Hmac;
use Phalcon\Encryption\Security\JWT\Token\Parser;
use Phalcon\Encryption\Security\JWT\Validator;

// Defaults to 'sha512'
$signer  = new Hmac();

// Builder object
$builder = new Builder($signer);

$now        = new DateTimeImmutable();
$issued     = $now->getTimestamp();
$notBefore  = $now->modify('-1 minute')->getTimestamp();
$expires    = $now->modify('+1 day')->getTimestamp();
$passphrase = 'QcMpZ&b&mo3TPsPk668J6QH8JA$&U&m2';

// Setup
$builder
->setAudience('https://target.phalcon.io')  // aud
->setContentType('application/json')        // cty - header
->setExpirationTime($expires)               // exp 
->setId('abcd123456789')                    // JTI id 
->setIssuedAt($issued)                      // iat 
->setIssuer('https://phalcon.io')           // iss 
->setNotBefore($notBefore)                  // nbf
->setSubject('my subject for this claim')   // sub
->setPassphrase($passphrase)                // password 
;

// Phalcon\Encryption\Security\JWT\Token\Token
$tokenObject = $builder->getToken();

echo $tokenObject->getToken();

// eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiIsImN0eSI6ImFwcGxpY2F0aW9uXC9qc29uIn0.
// eyJhdWQiOlsiaHR0cHM6XC9cL3RhcmdldC5waGFsY29uLmlvIl0sImV4cCI6MTYxNDE4NTkxN
// ywianRpIjoiYWJjZDEyMzQ1Njc4OSIsImlhdCI6MTYxNDA5OTUxNywiaXNzIjoiaHR0cHM6XC
// 9cL3BoYWxjb24uaW8iLCJuYmYiOjE2MTQwOTk0NTcsInN1YiI6Im15IHN1YmplY3QgZm9yIHR
// oaXMgY2xhaW0ifQ.
// LdYevRZaQDZ2lul4CCQ5DymeP2ubcapTtgeezOZGIq7Meu7rFF1pv32b-AMWOxCS63CQz_jpm
// BPlPyOeEAkMbg
```

```php
// $tokenReceived is what we received
$tokenReceived = getMyTokenFromTheApplication();
$audience      = 'https://target.phalcon.io';
$now           = new DateTimeImmutable();
$issued        = $now->getTimestamp();
$notBefore     = $now->modify('-1 minute')->getTimestamp();
$expires       = $now->getTimestamp();
$id            = 'abcd123456789';
$issuer        = 'https://phalcon.io';

// Defaults to 'sha512'
$signer     = new Hmac();
$passphrase = 'QcMpZ&b&mo3TPsPk668J6QH8JA$&U&m2';

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

// Phalcon\Encryption\Security\JWT\Token\Token
$tokenObject = $parser->parse($tokenReceived);

// Phalcon\Encryption\Security\JWT\Validator
$validator = new Validator($tokenObject, 100); // Allow for a time shift of 100

# Run the validators
$validator
->validateAudience($audience)
->validateExpiration($expires)
->validateId($id)
->validateIssuedAt($issued)
->validateIssuer($issuer)
->validateNotBefore($notBefore)
->validateSignature($signer, $passphrase)
;

# Errors printed out (if any)
var_dump($validator->getErrors())
```

The above example gives a general view on how the component can be used to generate, parse, and validate JSON Web
Tokens.

## Objects

There are several utility components that live in the `Phalcon\Encryption\Security\JWT\Token` namespace, that help with
the issuing, parsing, and validating of JWT tokens

### Enum

[Phalcon\Encryption\Security\JWT\Token\Enum][security-jwt-token-enum] is a class that contains several constants. These
constants are the strings defined in [RFC 7915][rfc-7519]. You can use them if you wish or instead use their string
equivalents.

```php
<?php

class Enum
{
/**
 * Headers
 */
const TYPE         = "typ";
const ALGO         = "alg";
const CONTENT_TYPE = "cty";

/**
 * Claims
 */
const AUDIENCE        = "aud";
const EXPIRATION_TIME = "exp";
const ID              = "jti";
const ISSUED_AT       = "iat";
const ISSUER          = "iss";
const NOT_BEFORE      = "nbf";
const SUBJECT         = "sub";
}
```

### Item

[Phalcon\Encryption\Security\JWT\Token\Item][security-jwt-token-item] is used internally to store a payload as well as
its encoded state. Such payload can be the claims data or the headers' data. By using this component, we can easily
extract the necessary information for each Token.

### Signature

[Phalcon\Encryption\Security\JWT\Token\Signature][security-jwt-token-signature] is similar to
the [Phalcon\Encryption\Security\JWT\Token\Item][security-jwt-token-item], but it only holds the signature hash as well
as its encoded value.

### Token

[Phalcon\Encryption\Security\JWT\Token\Token][security-jwt-token-token] is the component responsible for storing and
calculating the JWT token. It accepts the headers, claims (
as [Phalcon\Encryption\Security\JWT\Token\Item][security-jwt-token-item] objects), and signature objects in its
constructor and exposes:

```php
public function getClaims(): Item
```

Return the claims collection

```php
public function getHeaders(): Item
```

Return the headers collection

```php
public function getPayload(): string
```

Return the payload. For a token `abcd.efgh.ijkl`, it will return `abcd.efgh`

```php
public function getSignature(): Signature
```

Return the signature

```php
public function getToken(): string
```

Return the token as a string. For a token `abcd.efgh.ijkl` it will return `abcd.efgh.ijkl`.

```php
public function validate(Validator $validator): array
```

Run all validators against the token data. Return the errors array from the validator

```php
public function verify(SignerInterface $signer, string $key): bool
```

Verify the signature of the token

### Signer

**Supported signers**

:::info[NOTE]
Currently the library supports HMAC signers (symmetric): `sha512`, `sha384`, and `sha256`. The `none` signer is available for development only and should not be used in production.
:::

In order to create a JWT token, we need to supply a Signing algorithm. By default, the builder uses "
none" ([Phalcon\Encryption\Security\JWT\Signer\None][security-jwt-signer-none]). You can however use the HMAC
signer ([Phalcon\Encryption\Security\JWT\Signer\Hmac][security-jwt-signer-hmac]). Also, for further customization, you
can utilize the supplied [Phalcon\Encryption\Security\JWT\Signer\SignerInterface][security-jwt-signer-signerinterface]
interface.

```php
<?php

use Phalcon\Encryption\Security\JWT\Signer\Hmac;

$signer  = new Hmac();
```

**None**

This signer is provided mostly for development purposes. You should always sign your JWT tokens.

**HMAC**

The HMAC signer supports the `sha512`, `sha384`, and `sha256` algorithms. If none is supplied, the `sha512` is
automatically selected. If you supply a different algorithm,
a [Phalcon\Encryption\Security\JWT\Exceptions\UnsupportedAlgorithmException][security-jwt-exceptions-unsupportedalgorithmexception]
will be raised. The algorithm is set in the constructor.

```php
<?php

use Phalcon\Encryption\Security\JWT\Signer\Hmac;

$signer  = new Hmac();
$signer  = new Hmac('sha512');
$signer  = new Hmac('sha384');
$signer  = new Hmac('sha256');
$signer  = new Hmac('sha111'); // exception
```

The component utilizes the [hash_equals][hash-equals] and [hash_hmac][hash-hmac] PHP methods internally to verify and
sign the payload. It exposes the following methods:

```php
public function getAlgHeader(): string
```

Returns a string identifying the algorithm. For the HMAC algorithms, it will return:

| Algorithm | `getAlgHeader` |
|:---------:|:--------------:|
| `sha512`  |    `HS512`     |
| `sha384`  |    `HS384`     |
| `sha256`  |    `HS256`     |

```php
public function sign(string $payload, string $passphrase): string
```

Returns the hash of the payload using the passphrase

```php
public function verify(string $source, string $payload, string $passphrase): bool
```

Verifies that the hashed source string is the same as the hash of the payload with the passphrase.

## Issuing Tokens

A Builder component ([Phalcon\Encryption\Security\JWT\Builder][security-jwt-builder]) is available, utilizing chained
methods, and ready to be used to create JWT tokens. All you have to do is instantiate the Builder object, configure your
token, and call `getToken()`. This will return a [Phalcon\Encryption\Security\JWT\Token\Token][security-jwt-token-token]
object which contains all the necessary information for your token. When instantiating the builder component, you have
to supply the signer class. In the example below we use
the [Phalcon\Encryption\Security\JWT\Signer\Hmac][security-jwt-signer-hmac] signer.

All setters in this component are chainable.

```php
<?php

use Phalcon\Encryption\Security\JWT\Builder;
use Phalcon\Encryption\Security\JWT\Signer\Hmac;

// Defaults to 'sha512'
$signer  = new Hmac();

// Builder object
$builder = new Builder($signer);
```

### Methods

```php
public function __construct(SignerInterface $signer): Builder
```

Constructor

```php
public function init(): Builder
```

Initializes the object - useful when you want to reuse the same builder

```php
public function addClaim(string $name, mixed $value): Builder
```

Adds a custom claim in the claims collection

```php
public function getAudience(): array
```

---
Returns the `aud` contents. If `aud` is not set, this method returns an empty array.

```php
public function getClaims(): array
```

Returns the claims as an array

```php
public function getContentType(): ?string
```

Returns the content type (`cty` - headers)

```php
public function getExpirationTime(): ?int
```

Returns the `exp` contents

```php
public function getHeaders(): array
```

Returns the headers as an array

```php
public function getId(): ?string
```

Returns the `jti` contents (ID of this JWT)

```php
public function getIssuedAt(): ?int
```

Returns the `iat` contents

```php
public function getIssuer(): ?string
```

Returns the `iss` contents

```php
public function getNotBefore(): ?int
```

Returns the `nbf` contents

```php
public function getSubject(): ?string
```

Returns the `sub` contents

```php
public function getToken(): Token
```

Returns the token

```php
public function getPassphrase(): string
```

Returns the supplied passphrase

```php
public function setAudience(array|string $audience): Builder
```

Sets the audience (`aud`). If the parameter passed is not an array or a string,
a [Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException][security-jwt-exceptions-validatorexception] will be
thrown.

```php
public function setContentType(string $contentType): Builder
```

Sets the content type (`cty` - headers)

```php
public function setExpirationTime(int $timestamp): Builder
```

Sets the audience (`exp`). If the `$timestamp` is less than the current time,
a [Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException][security-jwt-exceptions-validatorexception] will be
thrown.

```php
public function setId(string $id): Builder
```

Sets the id (`jti`).

```php
public function setIssuedAt(int $timestamp): Builder
```

Sets the issued at time (`iat`).

```php
public function setIssuer(string $issuer): Builder
```

Sets the issuer (`iss`).

```php
public function setNotBefore(int $timestamp): Builder
```

Sets the not before time (`nbf`). If the `$timestamp` is greater than the current time,
a [Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException][security-jwt-exceptions-validatorexception] will be
thrown.

```php
public function setSubject(string $subject): Builder
```

Sets the subject (`sub`).

```php
public function setPassphrase(string $passphrase): Builder
```

Sets the passphrase. A weak passphrase raises
a [Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException][security-jwt-exceptions-validatorexception].

The passphrase must:

- be at least 16 characters long
- contain at least one uppercase letter
- contain at least one lowercase letter
- contain at least one digit
- contain at least one special character

```php
private function setClaim(string $name, $value): Builder
```

Sets a claim value in the internal collection.

### Example

```php
<?php

use Phalcon\Encryption\Security\JWT\Builder;
use Phalcon\Encryption\Security\JWT\Signer\Hmac;
use Phalcon\Encryption\Security\JWT\Token\Parser;
use Phalcon\Encryption\Security\JWT\Validator;

// 'sha512'
$signer  = new Hmac();

$builder = new Builder($signer);

$now        = new DateTimeImmutable();
$issued     = $now->getTimestamp();
$notBefore  = $now->modify('-1 minute')->getTimestamp();
$expires    = $now->modify('+1 day')->getTimestamp();
$passphrase = 'QcMpZ&b&mo3TPsPk668J6QH8JA$&U&m2';

$builder
->setAudience('https://target.phalcon.io')  // aud
->setContentType('application/json')        // cty - header
->setExpirationTime($expires)               // exp 
->setId('abcd123456789')                    // JTI id 
->setIssuedAt($issued)                      // iat 
->setIssuer('https://phalcon.io')           // iss 
->setNotBefore($notBefore)                  // nbf
->setSubject('my subject for this claim')   // sub
->setPassphrase($passphrase)                // password 
;

// Phalcon\Encryption\Security\JWT\Token\Token 
$tokenObject = $builder->getToken();

echo $tokenObject->getToken();

// eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiIsImN0eSI6ImFwcGxpY2F0aW9uXC9qc29uIn0.
// eyJhdWQiOlsiaHR0cHM6XC9cL3RhcmdldC5waGFsY29uLmlvIl0sImV4cCI6MTYxNDE4NTkxN
// ywianRpIjoiYWJjZDEyMzQ1Njc4OSIsImlhdCI6MTYxNDA5OTUxNywiaXNzIjoiaHR0cHM6XC
// 9cL3BoYWxjb24uaW8iLCJuYmYiOjE2MTQwOTk0NTcsInN1YiI6Im15IHN1YmplY3QgZm9yIHR
// oaXMgY2xhaW0ifQ.
// LdYevRZaQDZ2lul4CCQ5DymeP2ubcapTtgeezOZGIq7Meu7rFF1pv32b-AMWOxCS63CQz_jpm
// BPlPyOeEAkMbg
```

## Validating Tokens

In order to validate a token you will need to create a
new [Phalcon\Encryption\Security\JWT\Validator][security-jwt-validator] object. The object can be constructed using
a [Phalcon\Encryption\Security\JWT\Token\Token][security-jwt-token-token] object and an offset in time to handle
time/clock shifts of the sending and receiving computers.

In order to parse the JWT received and convert it to
a [Phalcon\Encryption\Security\JWT\Token\Token][security-jwt-token-token] object, you will need to use
a [Phalcon\Encryption\Security\JWT\Token\Parser][security-jwt-token-parser] object and parse it.

### Validator

```php
$parser = new Parser();

$tokenObject = $parser->parse($tokenReceived);

$validator = new Validator($tokenObject, 100); // allow for a time shift of 100
```

You can use the [Phalcon\Encryption\Security\JWT\Validator][security-jwt-validator] object to validate each claim by
calling the `validate*` methods with the necessary parameters (taken from
the [Phalcon\Encryption\Security\JWT\Token\Token][security-jwt-token-token]). The internal `errors` array in
the [Phalcon\Encryption\Security\JWT\Validator][security-jwt-validator] will be populated accordingly, returning the
results with the `getErrors()` method.

#### Methods

```php
public function __construct(Token $token, int $timeShift = 0)
```

Constructor

```php
public function get(string $claim): mixed | null
```

Returns a claim's value - `null` if the claim does not exist

```php
public function set(string $claim, mixed $value): Validator
```

Sets a claim and its value

```php
public function setToken(Token $token): Validator
```

Sets the token object.

```php
public function validateAudience(array|string $audience): Validator
```

Validates the audience. If it is not included in the token's `aud`,
a [Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException][security-jwt-exceptions-validatorexception] will be
thrown.

```php
public function validateClaim(string $name, mixed $value): Validator
```

Validates a custom claim by name against an expected value.

In a validator example chain, include one custom claim check, e.g.:

```php
$validator
->validateAudience($audience)
->validateIssuer($issuer)
->validateClaim("tenantId", "acme")
;
```

```php
public function validateExpiration(int $timestamp): Validator
```

Validates the expiration time. If the `exp` value stored in the token is less than now,
a [Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException][security-jwt-exceptions-validatorexception] will be
thrown.

```php
public function validateId(string $id): Validator
```

Validates the id. If it is not the same as the `jti` value stored in the token,
a [Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException][security-jwt-exceptions-validatorexception] will be
thrown.

```php
public function validateIssuedAt(int $timestamp): Validator
```

Validates the `issued at` time. If the `iat` value stored in the token is greater than now,
a [Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException][security-jwt-exceptions-validatorexception] will be
thrown.

```php
public function validateIssuer(string $issuer): Validator
```

Validates the issuer. If it is not the same as the `iss` value stored in the token,
a [Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException][security-jwt-exceptions-validatorexception] will be
thrown.

```php
public function validateNotBefore(int $timestamp): Validator
```

Validates the not before time. If the `nbf` value stored in the token is greater than now,
a [Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException][security-jwt-exceptions-validatorexception] will be
thrown.

```php
public function validateSignature(SignerInterface $signer, string $passphrase): Validator
```

Validates the signature of the token. If the signature is not valid,
a [Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException][security-jwt-exceptions-validatorexception] will be
thrown.

#### Example

```php
<?php

use Phalcon\Encryption\Security\JWT\Signer\Hmac;
use Phalcon\Encryption\Security\JWT\Token\Parser;
use Phalcon\Encryption\Security\JWT\Validator;

// eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiIsImN0eSI6ImFwcGxpY2F0aW9uXC9qc29uIn0.
// eyJhdWQiOlsiaHR0cHM6XC9cL3RhcmdldC5waGFsY29uLmlvIl0sImV4cCI6MTYxNDE4NTkxN
// ywianRpIjoiYWJjZDEyMzQ1Njc4OSIsImlhdCI6MTYxNDA5OTUxNywiaXNzIjoiaHR0cHM6XC
// 9cL3BoYWxjb24uaW8iLCJuYmYiOjE2MTQwOTk0NTcsInN1YiI6Im15IHN1YmplY3QgZm9yIHR
// oaXMgY2xhaW0ifQ.
// LdYevRZaQDZ2lul4CCQ5DymeP2ubcapTtgeezOZGIq7Meu7rFF1pv32b-AMWOxCS63CQz_jpm
// BPlPyOeEAkMbg

$tokenReceived = getMyTokenFromTheApplication();
$audience      = 'https://target.phalcon.io';
$now           = new DateTimeImmutable();
$issued        = $now->getTimestamp();
$notBefore     = $now->modify('-1 minute')->getTimestamp();
$expires       = $now->getTimestamp();
$id            = 'abcd123456789';
$issuer        = 'https://phalcon.io';

// 'sha512'
$signer     = new Hmac();
$passphrase = 'QcMpZ&b&mo3TPsPk668J6QH8JA$&U&m2';

$parser      = new Parser();

// Phalcon\Encryption\Security\JWT\Token\Token 
$tokenObject = $parser->parse($tokenReceived);

// Phalcon\Encryption\Security\JWT\Validator 
$validator = new Validator($tokenObject, 100); // allow for a time shift of 100

$validator
->validateAudience($audience)
->validateExpiration($expires)
->validateId($id)
->validateIssuedAt($issued)
->validateIssuer($issuer)
->validateNotBefore($notBefore)
->validateSignature($signer, $passphrase)
;

var_dump($validator->getErrors());
```

### Token

As an alternative, you can `verify()` and `validate()` your token using the relevant methods in
the [Phalcon\Encryption\Security\JWT\Token\Token][security-jwt-token-token] object.

#### Methods

```php
public function validate(Validator $validator): array
```

Validate the token claims. The validators that are executed are:

- `validateAudience()`
- `validateExpiration()`
- `validateId()`
- `validateIssuedAt()`
- `validateIssuer()`
- `validateNotBefore()`

You can extend the [Phalcon\Encryption\Security\JWT\Validator][security-jwt-validator]
and [Phalcon\Encryption\Security\JWT\Token\Token][security-jwt-token-token] objects to include more validators and
execute them (as seen below).

```php
public function verify(SignerInterface $signer, string $key): bool
```

Verify the signature of the token

#### Example

```php
<?php

use Phalcon\Encryption\Security\JWT\Enum;
use Phalcon\Encryption\Security\JWT\Signer\Hmac;
use Phalcon\Encryption\Security\JWT\Token\Parser;
use Phalcon\Encryption\Security\JWT\Validator;

// eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiIsImN0eSI6ImFwcGxpY2F0aW9uXC9qc29uIn0.
// eyJhdWQiOlsiaHR0cHM6XC9cL3RhcmdldC5waGFsY29uLmlvIl0sImV4cCI6MTYxNDE4NTkxN
// ywianRpIjoiYWJjZDEyMzQ1Njc4OSIsImlhdCI6MTYxNDA5OTUxNywiaXNzIjoiaHR0cHM6XC
// 9cL3BoYWxjb24uaW8iLCJuYmYiOjE2MTQwOTk0NTcsInN1YiI6Im15IHN1YmplY3QgZm9yIHR
// oaXMgY2xhaW0ifQ.
// LdYevRZaQDZ2lul4CCQ5DymeP2ubcapTtgeezOZGIq7Meu7rFF1pv32b-AMWOxCS63CQz_jpm
// BPlPyOeEAkMbg

$tokenReceived = getMyTokenFromTheApplication();
$subject       = 'Mary had a little lamb';
$audience      = 'https://target.phalcon.io';
$now           = new DateTimeImmutable();
$issued        = $now->getTimestamp();
$notBefore     = $now->modify('-1 minute')->getTimestamp();
$expires       = $now->getTimestamp();
$id            = 'abcd123456789';
$issuer        = 'https://phalcon.io';

// 'sha512'
$signer     = new Hmac();
$passphrase = 'QcMpZ&b&mo3TPsPk668J6QH8JA$&U&m2';

$parser      = new Parser();

// Phalcon\Encryption\Security\JWT\Token\Token 
$tokenObject = $parser->parse($tokenReceived);

// Phalcon\Encryption\Security\JWT\Validator 
$validator = new Validator($tokenObject, 100); // allow for a time shift of 100

$validator
->set(Enum::AUDIENCE, $audience)
->set(Enum::EXPIRATION_TIME, $expires)
->set(Enum::ISSUER, $issuer)
->set(Enum::ISSUED_AT, $issued)
->set(Enum::ID, $id)
->set(Enum::NOT_BEFORE, $notBefore)
->set(Enum::SUBJECT, $subject)
;

$tokenObject->verify($signer, $passphrase);
$errors = $tokenObject->validate($validator);

var_dump($errors);
```

## Exceptions

Any exceptions thrown in the Security component will be of the namespace `Phalcon\Encryption\Security\JWT\*`. You can
use this exception to selectively catch exceptions thrown only from this component. There are two exceptions raised.
First, if you supply the wrong algorithm string when instantiating
the [Phalcon\Encryption\Security\JWT\Signer\Hmac][security-jwt-signer-hmac] component. This exception
is [Phalcon\Encryption\Security\JWT\Exceptions\UnsupportedAlgorithmException][security-jwt-exceptions-unsupportedalgorithmexception].

The second exception is thrown when validating a JWT. This exception
is [Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException][security-jwt-exceptions-validatorexception].

```php
<?php

use Phalcon\Mvc\Controller;
use Phalcon\Encryption\Security\JWT\Builder;
use Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException;
use Phalcon\Encryption\Security\JWT\Signer\Hmac;
use Phalcon\Encryption\Security\JWT\Validator;

class IndexController extends Controller
{
public function index()
{
    try {
        $signer     = new Hmac();
        $builder    = new Builder($signer);
        $expires    = strtotime('+1 day');
        $issued     = strtotime('now') + 100;
        $notBefore  = strtotime('-1 day');
        $passphrase = '&vsJBETaizP3A3VX&TPMJUqi48fJEgN7';

        return $builder
            ->setAudience('my-audience')
            ->setExpirationTime($expires)
            ->setIssuer('Phalcon JWT')
            ->setIssuedAt($issued)
            ->setId('PH-JWT')
            ->setNotBefore($notBefore)
            ->setSubject('Mary had a little lamb')
            ->setPassphrase($passphrase)
            ->getToken()
        ;

        $validator = new Validator($token);
        $validator->validateAudience("unknown");
    } catch (Exception $ex) {
        echo $ex->getMessage(); // Validation: audience not allowed
    }
}
}
```

### Granular Exceptions

As of 5.13.1 the component raises granular subclasses so callers can catch a specific failure mode. Validation-related
classes extend `ValidatorException`; structural-input errors extend `InvalidArgumentException`; the HMAC algorithm
rejection extends `UnsupportedAlgorithmException`.

| Class                                                                 | Parent                                                                     | Thrown when                                                                    |
|-----------------------------------------------------------------------|----------------------------------------------------------------------------|--------------------------------------------------------------------------------|
| `Phalcon\Encryption\Security\JWT\Exceptions\EmptyPassphrase`          | `Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException`            | A signing or validation call is made without a passphrase.                     |
| `Phalcon\Encryption\Security\JWT\Exceptions\InvalidAudience`          | `Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException`            | The token's `aud` claim does not match the audience supplied to the validator. |
| `Phalcon\Encryption\Security\JWT\Exceptions\InvalidAudienceType`      | `Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException`            | The audience supplied to the validator is not a string or array of strings.    |
| `Phalcon\Encryption\Security\JWT\Exceptions\InvalidClaims`            | `InvalidArgumentException`                                                 | The decoded claims segment is not a JSON object.                               |
| `Phalcon\Encryption\Security\JWT\Exceptions\InvalidExpirationTime`    | `Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException`            | The token has expired (`exp` claim is in the past).                            |
| `Phalcon\Encryption\Security\JWT\Exceptions\InvalidHeader`            | `InvalidArgumentException`                                                 | The decoded header segment is not a JSON object.                               |
| `Phalcon\Encryption\Security\JWT\Exceptions\InvalidNotBefore`         | `Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException`            | The token is presented before its `nbf` claim.                                 |
| `Phalcon\Encryption\Security\JWT\Exceptions\MalformedJwtString`       | `InvalidArgumentException`                                                 | The supplied JWT string does not have three dot-separated segments.            |
| `Phalcon\Encryption\Security\JWT\Exceptions\MissingJwtTypHeader`      | `InvalidArgumentException`                                                 | The decoded header is missing the `typ` field.                                 |
| `Phalcon\Encryption\Security\JWT\Exceptions\UnsupportedHmacAlgorithm` | `Phalcon\Encryption\Security\JWT\Exceptions\UnsupportedAlgorithmException` | The HMAC signer is constructed with an algorithm not in the supported list.    |
| `Phalcon\Encryption\Security\JWT\Exceptions\WeakPassphrase`           | `Phalcon\Encryption\Security\JWT\Exceptions\ValidatorException`            | The supplied passphrase is below the minimum strength threshold.               |

[rfc-7519]: https://datatracker.ietf.org/doc/html/rfc7519

[hash-hmac]: https://www.php.net/manual/en/function.hash-hmac.php

[hash-equals]: https://www.php.net/manual/en/function.hash-equals.php

[security-jwt-builder]: /5.13/api/phalcon_encryption/#encryptionsecurityjwtbuilder

[security-jwt-exceptions-unsupportedalgorithmexception]: /5.13/api/phalcon_encryption/#encryptionsecurityjwtexceptionsunsupportedalgorithmexception

[security-jwt-exceptions-validatorexception]: /5.13/api/phalcon_encryption/#encryptionsecurityjwtexceptionsvalidatorexception

[security-jwt-signer-abstractsigner]: /5.13/api/phalcon_encryption/#encryptionsecurityjwtsignerabstractsigner

[security-jwt-signer-hmac]: /5.13/api/phalcon_encryption/#encryptionsecurityjwtsignerhmac

[security-jwt-signer-none]: /5.13/api/phalcon_encryption/#encryptionsecurityjwtsignernone

[security-jwt-signer-signerinterface]: /5.13/api/phalcon_encryption/#encryptionsecurityjwtsignersignerinterface

[security-jwt-token-abstractitem]: /5.13/api/phalcon_encryption/#encryptionsecurityjwttokenabstractitem

[security-jwt-token-enum]: /5.13/api/phalcon_encryption/#encryptionsecurityjwttokenenum

[security-jwt-token-item]: /5.13/api/phalcon_encryption/#encryptionsecurityjwttokenitem

[security-jwt-token-parser]: /5.13/api/phalcon_encryption/#encryptionsecurityjwttokenparser

[security-jwt-token-signature]: /5.13/api/phalcon_encryption/#encryptionsecurityjwttokensignature

[security-jwt-token-token]: /5.13/api/phalcon_encryption/#encryptionsecurityjwttokentoken

[security-jwt-validator]: /5.13/api/phalcon_encryption/#encryptionsecurityjwtvalidator

Source: https://docs.phalcon.io/5.13/encryption-security-jwt/index.mdx
