128 lines
3.1 KiB
PHP
128 lines
3.1 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of jwt-auth.
|
|
*
|
|
* (c) Sean Tymon <tymon148@gmail.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Tymon\JWTAuth\Validators;
|
|
|
|
use Tymon\JWTAuth\Utils;
|
|
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
|
|
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
|
|
|
|
class PayloadValidator extends AbstractValidator
|
|
{
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $requiredClaims = ['iss', 'iat', 'exp', 'nbf', 'sub', 'jti'];
|
|
|
|
/**
|
|
* @var int
|
|
*/
|
|
protected $refreshTTL = 20160;
|
|
|
|
/**
|
|
* Run the validations on the payload array.
|
|
*
|
|
* @param array $value
|
|
* @return void
|
|
*/
|
|
public function check($value)
|
|
{
|
|
$this->validateStructure($value);
|
|
|
|
if (! $this->refreshFlow) {
|
|
$this->validateTimestamps($value);
|
|
} else {
|
|
$this->validateRefresh($value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Ensure the payload contains the required claims and
|
|
* the claims have the relevant type.
|
|
*
|
|
* @param array $payload
|
|
* @throws \Tymon\JWTAuth\Exceptions\TokenInvalidException
|
|
* @return bool
|
|
*/
|
|
protected function validateStructure(array $payload)
|
|
{
|
|
if (count(array_diff($this->requiredClaims, array_keys($payload))) !== 0) {
|
|
throw new TokenInvalidException('JWT payload does not contain the required claims');
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Validate the payload timestamps.
|
|
*
|
|
* @param array $payload
|
|
* @throws \Tymon\JWTAuth\Exceptions\TokenExpiredException
|
|
* @throws \Tymon\JWTAuth\Exceptions\TokenInvalidException
|
|
* @return bool
|
|
*/
|
|
protected function validateTimestamps(array $payload)
|
|
{
|
|
if (isset($payload['nbf']) && Utils::timestamp($payload['nbf'])->isFuture()) {
|
|
throw new TokenInvalidException('Not Before (nbf) timestamp cannot be in the future', 401);
|
|
}
|
|
|
|
if (isset($payload['iat']) && Utils::timestamp($payload['iat'])->isFuture()) {
|
|
throw new TokenInvalidException('Issued At (iat) timestamp cannot be in the future', 401);
|
|
}
|
|
|
|
if (Utils::timestamp($payload['exp'])->isPast()) {
|
|
throw new TokenExpiredException('Token has expired');
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check the token in the refresh flow context.
|
|
*
|
|
* @param $payload
|
|
* @return bool
|
|
*/
|
|
protected function validateRefresh(array $payload)
|
|
{
|
|
if (isset($payload['iat']) && Utils::timestamp($payload['iat'])->addMinutes($this->refreshTTL)->isPast()) {
|
|
throw new TokenExpiredException('Token has expired and can no longer be refreshed', 401);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Set the required claims.
|
|
*
|
|
* @param array $claims
|
|
*/
|
|
public function setRequiredClaims(array $claims)
|
|
{
|
|
$this->requiredClaims = $claims;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set the refresh ttl.
|
|
*
|
|
* @param int $ttl
|
|
*/
|
|
public function setRefreshTTL($ttl)
|
|
{
|
|
$this->refreshTTL = $ttl;
|
|
|
|
return $this;
|
|
}
|
|
}
|