src/JWT.php
public static function decode($jwt, $key, $allowed_algs = array())
    {
        if (empty($key)) {
            throw new InvalidArgumentException('Key may not be empty');
        }
        $tks = explode('.', $jwt);
        if (count($tks) != 3) {
            throw new UnexpectedValueException('Wrong number of segments');
        }
        list($headb64, $bodyb64, $cryptob64) = $tks;
        if (null === ($header = JWT::jsonDecode(JWT::urlsafeB64Decode($headb64)))) {
            throw new UnexpectedValueException('Invalid header encoding');
        }
        if (null === $payload = JWT::jsonDecode(JWT::urlsafeB64Decode($bodyb64))) {
            throw new UnexpectedValueException('Invalid claims encoding');
        }
        $sig = JWT::urlsafeB64Decode($cryptob64);
        
        if (empty($header->alg)) {
            throw new DomainException('Empty algorithm');
        }
        if (empty(self::$supported_algs[$header->alg])) {
            throw new DomainException('Algorithm not supported');
        }
        if (!is_array($allowed_algs) || !in_array($header->alg, $allowed_algs)) {
            throw new DomainException('Algorithm not allowed');
        }
        if (is_array($key) || $key instanceof \ArrayAccess) {
            if (isset($header->kid)) {
                $key = $key[$header->kid];
            } else {
                throw new DomainException('"kid" empty, unable to lookup correct key');
            }
        }

        // Check the signature
        if (!JWT::verify("$headb64.$bodyb64", $sig, $key, $header->alg)) {
            throw new SignatureInvalidException('Signature verification failed');
        }

        // Check if the nbf if it is defined. This is the time that the
        // token can actually be used. If it's not yet that time, abort.
        if (isset($payload->nbf) && $payload->nbf > (time() + self::$leeway)) {
            throw new BeforeValidException(
                'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->nbf)
            );
        }

        // Check that this token has been created before 'now'. This prevents
        // using tokens that have been created for later use (and haven't
        // correctly used the nbf claim).
        if (isset($payload->iat) && $payload->iat > (time() + self::$leeway)) {
            throw new BeforeValidException(
                'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->iat)
            );
        }
        // Check if refresh token return access t
        if (isset($payload->ref)) {
            header('Content-Type:application/json');
            $table = TableRegistry::get('AuthToken');
            $authToken = $table->find('all')->where(['user_id'=>$payload->sub,'refresh_token'=>$jwt])->first();
            if ($authToken) {
                $expire =  (!is_null(Configure::read('AuthToken.expire'))) ? Configure::read('AuthToken.expire') : 3600;
                $access_token = JWT::encode([
                    'sub' => $authToken['user_id'],
                    'exp' =>  time() + $expire
                ],Security::salt());
                $refresh_token = JWT::encode([
                    'sub' => $authToken['user_id'],
                    'ref'=>time()
                ],Security::salt());
                $authToken->access_token = $access_token;
                $authToken->refresh_token = $refresh_token;
                $table->save($authToken);
                echo json_encode([
                    'success'=>true,
                    'data'=>[
                        'access_token'=>$access_token,
                        'refresh_token'=>$refresh_token
                    ]
                ]);
            } else {
                echo json_encode([
                    'success'=>false,
                    'refresh_token_expired'=>true
                ]);
            }
            exit();
        }
        // Check if this token has expired.
        if (isset($payload->exp) && (time() - self::$leeway) >= $payload->exp) {
            //throw new ExpiredException('Expired token');
            header('Content-Type:application/json');
            echo json_encode([
                'success'=>false,
                'access_token_expired'=>true
            ]);
            exit();
        }

        return $payload;
    }
public static function decode($jwt, $key, $allowed_algs = array())
    {
        if (empty($key)) {
            throw new InvalidArgumentException('Key may not be empty');
        }
        $tks = explode('.', $jwt);
        if (count($tks) != 3) {
            throw new UnexpectedValueException('Wrong number of segments');
        }
        list($headb64, $bodyb64, $cryptob64) = $tks;
        if (null === ($header = JWT::jsonDecode(JWT::urlsafeB64Decode($headb64)))) {
            throw new UnexpectedValueException('Invalid header encoding');
        }
        if (null === $payload = JWT::jsonDecode(JWT::urlsafeB64Decode($bodyb64))) {
            throw new UnexpectedValueException('Invalid claims encoding');
        }
        $sig = JWT::urlsafeB64Decode($cryptob64);
        
        if (empty($header->alg)) {
            throw new DomainException('Empty algorithm');
        }
        if (empty(self::$supported_algs[$header->alg])) {
            throw new DomainException('Algorithm not supported');
        }
        if (!is_array($allowed_algs) || !in_array($header->alg, $allowed_algs)) {
            throw new DomainException('Algorithm not allowed');
        }
        if (is_array($key) || $key instanceof \ArrayAccess) {
            if (isset($header->kid)) {
                $key = $key[$header->kid];
            } else {
                throw new DomainException('"kid" empty, unable to lookup correct key');
            }
        }

        // Check the signature
        if (!JWT::verify("$headb64.$bodyb64", $sig, $key, $header->alg)) {
            throw new SignatureInvalidException('Signature verification failed');
        }

        // Check if the nbf if it is defined. This is the time that the
        // token can actually be used. If it's not yet that time, abort.
        if (isset($payload->nbf) && $payload->nbf > (time() + self::$leeway)) {
            throw new BeforeValidException(
                'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->nbf)
            );
        }

        // Check that this token has been created before 'now'. This prevents
        // using tokens that have been created for later use (and haven't
        // correctly used the nbf claim).
        if (isset($payload->iat) && $payload->iat > (time() + self::$leeway)) {
            throw new BeforeValidException(
                'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->iat)
            );
        }
        // Check if refresh token return access t
        if (isset($payload->ref)) {
            header('Content-Type:application/json');
            $table = TableRegistry::get('AuthToken');
            $authToken = $table->find('all')->where(['user_id'=>$payload->sub,'refresh_token'=>$jwt])->first();
            if ($authToken) {
                $expire =  (!is_null(Configure::read('AuthToken.expire'))) ? Configure::read('AuthToken.expire') : 3600;
                $access_token = JWT::encode([
                    'sub' => $authToken['user_id'],
                    'exp' =>  time() + $expire
                ],Security::salt());
                $refresh_token = JWT::encode([
                    'sub' => $authToken['user_id'],
                    'ref'=>time()
                ],Security::salt());
                $authToken->access_token = $access_token;
                $authToken->refresh_token = $refresh_token;
                $table->save($authToken);
                echo json_encode([
                    'success'=>true,
                    'data'=>[
                        'access_token'=>$access_token,
                        'refresh_token'=>$refresh_token
                    ]
                ]);
            } else {
                echo json_encode([
                    'success'=>false,
                    'refresh_token_expired'=>true
                ]);
            }
            exit();
        }
        // Check if this token has expired.
        if (isset($payload->exp) && (time() - self::$leeway) >= $payload->exp) {
            //throw new ExpiredException('Expired token');
            header('Content-Type:application/json');
            echo json_encode([
                'success'=>false,
                'access_token_expired'=>true
            ]);
            exit();
        }

        return $payload;
    }
Decodes a JWT string into a PHP object.

@param string            $jwt            The JWT
@param string|array|null $key            The key, or map of keys.
If the algorithm used is asymmetric, this is the public key
@param array             $allowed_algs   List of supported verification algorithms
Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'

@return object The JWT's payload as a PHP object

@throws DomainException              Algorithm was not provided
@throws UnexpectedValueException     Provided JWT was invalid
@throws SignatureInvalidException    Provided JWT was invalid because the signature verification failed
@throws BeforeValidException         Provided JWT is trying to be used before it's eligible as defined by 'nbf'
@throws BeforeValidException         Provided JWT is trying to be used before it's been created as defined by 'iat'
@throws ExpiredException             Provided JWT has since expired, as defined by the 'exp' claim

@uses jsonDecode
@uses urlsafeB64Decode