Skip to main content
Version: 4.x

Policier JWT Auth

Installation​

Policier lets you validate requests via JWT

To set up the installation strategy, you need to use composer (the PHP package manager) like this.

composer require bowphp/policier

Configuration​

You can review all the configuration options here.

return [
/**
* Token expiration time
*/
"exp" => 3600,

/**
* The token becomes usable after this time
*/
"nbf" => 60,

/**
* The token was issued
*/
"iat" => 60,

/**
* Configures the issuer
*/
"iss" => "localhost",

/**
* Configures the audience
*/
"aud" => "localhost",

/**
* Hashing algorithm used
*
* HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512,
*/
"alg" => "HS512",

/**
* Your signature; this field is required for all hashing types except RSA
*/
'signkey' => null,

/**
* Signature using your RSA; this will load automatically if the hashing key is of RSA type
*/
"keychain" => [
/**
* Path to your private key
*/
"private" => null,

/**
* Path to your public key
*/
"public" => null
]
];

Usage​

Policier is very simple to use and has a clear API. The configuration returns a singleton.

use Policier\Policier;

$configure = require "/path/to/config/file.php";

$policier = Policier::configure($configure);

You can also do it like this:

use Policier\Policier;

$configure = require "/path/to/config/file.php";

Policier::configure($configure);

$policier = Policier::getInstance();

After configuration, you can use the policier helper:

policier($action, ...$args);

The action value must be one of these values: encode, decode, parse, verify, validate.

Updating or Retrieving the Configuration​

Updating the Configuration​

You can update the base configuration with the setConfig method:

$policier->setConfig('exp', time() + 72000);

Retrieving the Configuration​

You can also obtain configuration information with the getConfig method:

$policier->getConfig('exp');

Encoding a Token​

Quickly encode a token:

$id = uniqid();

$claims = [
"name" => "Franck",
"nickname" => "papac",
"logged" => true
];

$token = $policier->encode($id, $claims);

$token->expireIn(); // Expired In
$token->getToken(); // Token value

echo $token;
//=> eyJ0eX...OiJKV1.eyJpc3Mi...OiJsb2.l7v0bS0r...qnK1IeR

$token is an instance of Policier\Token and implements the magic method __toString. You can get the expiration time with expiredIn and getToken to retrieve the token value.

Via the helper:

policier('encode', $id, $claims);

Decoding a Token​

Same thing for decoding a token:

$result = $policier->decode($token);
$result['headers'];

echo $result['claims']['name'];
//=> Franck

Via the helper:

policier('decode', $token);

Parsing a Token​

$token = $policier->parse($token);

$token->hasHeader("old") // Check whether the header exists
$token->getHeader("alg", $default = null); // Get a header
$token->getHeaders(); // Get all headers

$token->hasClaim("name") // Check whether the claim exists
$token->getClaim("name", $default = null); // Get a claim
$token->getClaims(); // Get all claims

$token->isExpired(); // Check whether the token has expired

echo $token->getClaim("name");
//=> Franck

Via the helper:

policier('parse', $token);

Verifying a Token​

Check whether the token is valid against all JWT attributes.

$verified = $policier->verify($token);

if ($verified) {
echo "Token is valid";
} else {
echo "Token is not valid";
}

Via the helper:

policier('verify', $token);

Validating a Token​

Validate the token against the claim information and the exp information.

$claims = [
"name" => "Franck",
"nickname" => "papac",
"logged" => true
];

$validated = $policier->validate($token, $claims);

if ($validated) {
echo "The information is valid";
} else {
echo "The information is not valid";
}

Via the helper:

$claims = [
"name" => "Franck",
"nickname" => "papac",
"logged" => true
];

policier('validate', $token, $claims);

BowPHP and Policier​

If you use BowPHP, you can use the configuration plugin Policier\Bow\PolicierConfiguration::class and the middleware Policier\Bow\PolicierMiddleware::class.

Wire up the configuration in app\Kernel\Loader.php:

public function middlewares()
{
return [
...
'policier' => \Policier\Bow\PolicierMiddleware::class,
...
];
}

public function configurations()
{
return [
...
\Policier\Bow\PolicierConfiguration::class,
...
];
}

Use the middleware:

$app->get('/api', function () {
$token = policier()->getToken();
})->middleware('policier');

The token is parsed into the Policier instance during the middleware process via the plug method. After the middleware runs, you can:

  • Get the token with getToken
  • Decode the token with getDecodeToken
  • Parse the token with getParsedToken

Customizing the Middleware​

Note that you can create another middleware that will extend the default middleware Policier\Bow\PolicierMiddleware::class. This gives you the ability to change the error messages by overriding the getUnauthorizedMessage, getExpirateMessage, getExpirateCode, and getUnauthorizedCode methods.

php bow add:middleware CustomPolicierMiddleware

And then you can do this:


use Bow\Http\Request;
use Policier\Bow\PolicierMiddleware;

class CustomPolicierMiddleware extends PolicierMiddleware
{
/**
* Get the error message
*
* @return array
*/
public function getUnauthorizedMessage()
{
return [
'message' => 'unauthorized',
'error' => true
];
}

/**
* Get the token expiration message
*
* @return array
*/
public function getExpirationMessage()
{
return [
'message' => 'token is expired',
'expired' => true,
'error' => true
];
}

/**
* Get the unauthorized response code
*
* @return int
*/
public function getUnauthorizedStatusCode()
{
return 403;
}

/**
* Get the response code
*
* @return int
*/
public function getExpirationStatusCode()
{
return 403;
}
}

Publishing the middleware​

Publishing the custom middleware and overriding Policier's default one is very simple: you only need to add the middleware in the app/Kernel/Loader.php file with the api key.

public function middlewares()
{
return [
...
'policier' => \App\Middleware\CustomPolicierMiddleware::class,
...
];
}

Is something missing?

If you run into problems with the documentation or have suggestions to improve the documentation or the project in general, please open an issue for us, or send a tweet mentioning the Twitter account @bowframework or directly on github.