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'); } } if (!JWT::verify("{$headb64}.{$bodyb64}", $sig, $key, $header->alg)) { throw new SignatureInvalidException('Signature verification failed'); } if (isset($payload->nbf) && $payload->nbf > time() + self::$leeway) { throw new BeforeValidException('Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->nbf)); } if (isset($payload->iat) && $payload->iat > time() + self::$leeway) { throw new BeforeValidException('Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->iat)); } if (isset($payload->exp) && time() - self::$leeway >= $payload->exp) { throw new ExpiredException('Expired token'); } return $payload; }