/** * Decodes a JWT string into a PHP object. * * @param string $jwt The JWT * @param string|Array|null $key The secret key, or map of keys * @param bool $verify Don't skip verification process * * @return object The JWT's payload as a PHP object * @throws UnexpectedValueException Provided JWT was invalid * @throws DomainException Algorithm was not provided * * @uses jsonDecode * @uses urlsafeB64Decode */ public static function decode($jwt, $key = null, $verify = true) { $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 segment encoding'); } if (null === ($payload = JWT::jsonDecode(JWT::urlsafeB64Decode($bodyb64)))) { throw new UnexpectedValueException('Invalid segment encoding'); } $sig = JWT::urlsafeB64Decode($cryptob64); if ($verify) { if (empty($header->alg)) { throw new DomainException('Empty algorithm'); } if (is_array($key)) { 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 UnexpectedValueException('Signature verification failed'); } // Check token expiry time if defined. if (isset($payload->exp) && time() >= $payload->exp) { throw new UnexpectedValueException('Expired Token'); } } return $payload; }
/** * Validate Jwt token * * @param string $token_field_name * * @Then /^(?:the )?response should contain jwt token in field "([^"]*)"$/ */ public function responseShouldContainJwtToken($token_field_name) { $response = $this->response->json(); Assertions::assertArrayHasKey($token_field_name, $response); $tks = explode('.', $response[$token_field_name]); Assertions::assertEquals(3, count($tks)); list($headb64, $bodyb64, $cryptob64) = $tks; $sig = \JWT::urlsafeB64Decode($cryptob64); $header = \JWT::jsonDecode(\JWT::urlsafeB64Decode($headb64)); Assertions::assertTrue(\JWT::verify("{$headb64}.{$bodyb64}", $sig, $this->config['secret_key'], $header->alg)); }
/** * 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 */ 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 Exception('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 this token has expired. if (isset($payload->exp) && time() - self::$leeway >= $payload->exp) { throw new ExpiredException('Expired token'); } return $payload; }
public static function decode($jwt, $key, $allowed_algs = array()) { if (empty($key)) { throw new Exception('密钥不能为空'); } $tks = explode('.', $jwt); if (count($tks) != 3) { throw new Exception('分段有错误'); } list($headb64, $bodyb64, $cryptob64) = $tks; if (null === ($header = JWT::jsonDecode(JWT::urlsafeB64Decode($headb64)))) { throw new Exception('head编码错误'); } if (null === ($payload = JWT::jsonDecode(JWT::urlsafeB64Decode($bodyb64)))) { throw new Exception('声明编码错误'); } $sig = JWT::urlsafeB64Decode($cryptob64); if (empty($header->alg)) { throw new Exception('加密算法为空'); } if (empty(self::$supported_algs[$header->alg])) { throw new Exception('加密算法不支持'); } if (!is_array($allowed_algs) || !in_array($header->alg, $allowed_algs)) { throw new Exception('加密算法不允许使用'); } if (is_array($key) || $key instanceof \ArrayAccess) { if (isset($header->kid)) { $key = $key[$header->kid]; } else { throw new Exception('"kid"为空'); } } // Check the signature if (!JWT::verify("{$headb64}.{$bodyb64}", $sig, $key, $header->alg)) { throw new Exception('签名认证失败'); } if (isset($payload->nbf) && $payload->nbf > time() + self::$leeway) { throw new Exception('此日期前不能使用 ' . date(DateTime::ISO8601, $payload->nbf)); } if (isset($payload->iat) && $payload->iat > time() + self::$leeway) { throw new Exception('令牌此日期前不能使用 ' . date(DateTime::ISO8601, $payload->iat)); } // Check if this token has expired. if (isset($payload->exp) && time() - self::$leeway >= $payload->exp) { throw new Exception('令牌已过期'); } return $payload; }
/** * Decodes a JWT string into a PHP object. * * @param string $jwt The JWT * @param string|Array|null $key The secret key, or map of keys * @param bool $verify Don't skip verification process * * @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 */ public static function decode($jwt, $key = null, $verify = true) { $tks = explode('.', $jwt); if (count($tks) != 3) { return null; } list($headb64, $bodyb64, $cryptob64) = $tks; if (null === ($header = JWT::jsonDecode(JWT::urlsafeB64Decode($headb64)))) { return null; } if (null === ($payload = JWT::jsonDecode(JWT::urlsafeB64Decode($bodyb64)))) { return null; } $sig = JWT::urlsafeB64Decode($cryptob64); if ($verify) { if (empty($header->alg)) { return null; } if (is_array($key)) { if (isset($header->kid)) { $key = $key[$header->kid]; } else { return null; } } // Check the signature if (!JWT::verify("{$headb64}.{$bodyb64}", $sig, $key, $header->alg)) { return null; } // 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()) { return null; } // 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()) { return null; } // Check if this token has expired. if (isset($payload->exp) && time() >= $payload->exp) { return null; } } return $payload; }
/** * Decodes a JWT string into a PHP object. * * @param string $jwt The JWT * @param string|Array|null $key The secret key, or map of keys * @param bool $verify Don't skip verification process * * @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 */ public static function decode($jwt, $key = null, $verify = true) { $tks = JWT::split($jwt); if (null === ($header = JWT::jsonDecode(JWT::urlsafeB64Decode($tks['header'])))) { throw new UnexpectedValueException('Invalid header encoding'); } if (null === ($payload = JWT::jsonDecode(JWT::urlsafeB64Decode($tks['body'])))) { throw new UnexpectedValueException('Invalid claims encoding'); } $signature = JWT::urlsafeB64Decode($tks['sig']); if ($verify) { if (empty($header->alg)) { throw new DomainException('Empty algorithm'); } if (is_array($key)) { if (isset($header->kid)) { $key = $key[$header->kid]; } else { throw new DomainException('"kid" empty, unable to lookup correct key'); } } // Check the signature if ($key && !JWT::verify($tks['header'], $tks['body'], $signature, $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()) { 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()) { throw new BeforeValidException('Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->iat)); } // Check if this token has expired. if (isset($payload->exp) && time() >= $payload->exp) { throw new ExpiredException('Expired token'); } } return array($header, $payload, $signature); }
public function testVerify() { $msg = 'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.Iio6aHR0cDovL2FwcGxpY2F0aW9uL2NsaWNreT9ibGFoPTEuMjMmZi5vbz00NTYgQUMwMDAgMTIzIg.E_U8X2YpMT5K1cEiT_3-IvBYfrdIFIeVYeOqre_Z5Cg'; $tks = JWT::split($msg); list(, , $signature) = JWT::decode($tks); $this->assertTrue(JWT::verify($tks['header'], $tks['body'], $signature, 'my_key')); }
/** * Decodes a JWT string into a PHP object. * * @param string $jwt The JWT * @param string|Array|null $key The secret key, or map of keys * @param Array $allowed_algs List of supported verification algorithms * @param Array $options Extra options (audience, issuer, jwtid, subject) * * @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 * @throws InvalidAudienceException Provided JWT is having a 'aud' value other than audience option * @throws InvalidIssuerException Provided JWT is having a 'iss' value other than issuer option * @throws InvalidJWTIdException Provided JWT is having a 'jit' value other than jwtid option * @throws InvalidSubjectException Provided JWT is having a 'sub' value other than subject option * * @uses jsonDecode * @uses urlsafeB64Decode */ public static function decode($jwt, $key = null, $allowed_algs = array(), $options = array()) { $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 (isset($key)) { 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 this token has expired. if (isset($payload->exp) && time() - self::$leeway >= $payload->exp) { throw new ExpiredException('Expired token'); } if (isset($options['issuer']) && is_string($options['issuer'])) { if (!isset($payload->iss) || !is_string($payload->iss) || $payload->iss !== $options['issuer']) { throw new InvalidIssuerException('Invalid issuer'); } } if (isset($options['subject']) && is_string($options['subject'])) { if (!isset($payload->sub) || !is_string($payload->sub) || $payload->sub !== $options['subject']) { throw new InvalidSubjectException('Invalid subject'); } } if (isset($options['jwtid']) && is_string($options['jwtid'])) { if (!isset($payload->jti) || !is_string($payload->jti) || $payload->jti !== $options['jwtid']) { throw new InvalidJWTIdException('Invalid JWT ID'); } } if (isset($options['audience']) && (is_string($options['audience']) || is_array($options['audience']))) { if (!isset($payload->aud)) { throw new InvalidAudienceException('Invalid audience'); } $target = is_array($payload->aud) ? $payload->aud : array($payload->aud); $audiences = is_array($options['audience']) ? $options['audience'] : array($options['audience']); $audienceFound = false; foreach ($audiences as $audience) { if (is_string($audience) && array_search($audience, $payload->aud) !== false) { $audienceFound = true; break; } } if (!$audienceFound) { throw new InvalidAudienceException('Invalid audience'); } } } return $payload; }