From e232940cd26e01c117ea37198013845db5e5314d Mon Sep 17 00:00:00 2001 From: Sean Tymon Date: Thu, 7 Apr 2022 09:15:53 +0000 Subject: [PATCH 01/10] feat: Add PHP 8.1 and Laravel 9 support --- .github/workflows/phpunit.yml | 14 +- composer.json | 16 +- config/config.php | 5 +- src/Providers/AbstractServiceProvider.php | 4 - src/Providers/JWT/Lcobucci.php | 194 ++++++++++++++-------- src/Providers/JWT/Provider.php | 34 ++-- tests/Providers/JWT/LcobucciTest.php | 176 +++++++++++--------- 7 files changed, 259 insertions(+), 184 deletions(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index b9b5c25f7..2f31b4b70 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -14,18 +14,24 @@ jobs: strategy: fail-fast: false matrix: - php: [7.2, 7.3, 7.4, 8.0] - laravel: [6.*, 7.*, 8.*] + php: [7.2, 7.3, 7.4, 8.0, 8.1] + laravel: [6.*, 7.*, 8.*, 9.*] os: [ubuntu-latest] coverage: [none] include: - - php: 8.0 - laravel: 8.* + - php: 8.1 + laravel: 9.* os: ubuntu-latest coverage: xdebug exclude: - php: 7.2 laravel: 8.* + - php: 7.2 + laravel: 9.* + - php: 7.3 + laravel: 9.* + - php: 7.4 + laravel: 9.* name: '[P${{ matrix.php }}] [L${{ matrix.laravel }}] [${{ matrix.coverage }}]' diff --git a/composer.json b/composer.json index a15b39bf3..e1e43cc14 100644 --- a/composer.json +++ b/composer.json @@ -24,18 +24,18 @@ ], "require": { "php": "^7.2|^8.0", - "illuminate/auth": "^5.2|^6|^7|^8", - "illuminate/contracts": "^5.2|^6|^7|^8", - "illuminate/http": "^5.2|^6|^7|^8", - "illuminate/support": "^5.2|^6|^7|^8", - "lcobucci/jwt": "<3.4", + "illuminate/auth": "^5.2|^6|^7|^8|^9", + "illuminate/contracts": "^5.2|^6|^7|^8|^9", + "illuminate/http": "^5.2|^6|^7|^8|^9", + "illuminate/support": "^5.2|^6|^7|^8|^9", + "lcobucci/jwt": "^3.4|^4.0", "namshi/jose": "^7.0", "nesbot/carbon": "^1.0|^2.0" }, "require-dev": { - "illuminate/console": "^5.2|^6|^7|^8", - "illuminate/database": "^5.2|^6|^7|^8", - "illuminate/routing": "^5.2|^6|^7|^8", + "illuminate/console": "^5.2|^6|^7|^8|^9", + "illuminate/database": "^5.2|^6|^7|^8|^9", + "illuminate/routing": "^5.2|^6|^7|^8|^9", "mockery/mockery": ">=0.9.9", "phpunit/phpunit": "^8.5|^9.4", "yoast/phpunit-polyfills": "^0.2.0" diff --git a/config/config.php b/config/config.php index 8b7843b6b..f83234d16 100644 --- a/config/config.php +++ b/config/config.php @@ -129,12 +129,9 @@ | | Specify the hashing algorithm that will be used to sign the token. | - | See here: https://github.com/namshi/jose/tree/master/src/Namshi/JOSE/Signer/OpenSSL - | for possible values. - | */ - 'algo' => env('JWT_ALGO', 'HS256'), + 'algo' => env('JWT_ALGO', Tymon\JWTAuth\Providers\JWT\Provider::ALGO_HS256), /* |-------------------------------------------------------------------------- diff --git a/src/Providers/AbstractServiceProvider.php b/src/Providers/AbstractServiceProvider.php index ca312a40e..45d629969 100644 --- a/src/Providers/AbstractServiceProvider.php +++ b/src/Providers/AbstractServiceProvider.php @@ -12,8 +12,6 @@ namespace Tymon\JWTAuth\Providers; use Illuminate\Support\ServiceProvider; -use Lcobucci\JWT\Builder as JWTBuilder; -use Lcobucci\JWT\Parser as JWTParser; use Namshi\JOSE\JWS; use Tymon\JWTAuth\Blacklist; use Tymon\JWTAuth\Claims\Factory as ClaimFactory; @@ -167,8 +165,6 @@ protected function registerLcobucciProvider() { $this->app->singleton('tymon.jwt.provider.jwt.lcobucci', function ($app) { return new Lcobucci( - new JWTBuilder(), - new JWTParser(), $this->config('secret'), $this->config('algo'), $this->config('keys') diff --git a/src/Providers/JWT/Lcobucci.php b/src/Providers/JWT/Lcobucci.php index 126bdda30..6b1e40ff0 100644 --- a/src/Providers/JWT/Lcobucci.php +++ b/src/Providers/JWT/Lcobucci.php @@ -12,65 +12,49 @@ namespace Tymon\JWTAuth\Providers\JWT; use Exception; -use Illuminate\Support\Collection; -use Lcobucci\JWT\Builder; -use Lcobucci\JWT\Parser; -use Lcobucci\JWT\Signer\Ecdsa; -use Lcobucci\JWT\Signer\Ecdsa\Sha256 as ES256; -use Lcobucci\JWT\Signer\Ecdsa\Sha384 as ES384; -use Lcobucci\JWT\Signer\Ecdsa\Sha512 as ES512; -use Lcobucci\JWT\Signer\Hmac\Sha256 as HS256; -use Lcobucci\JWT\Signer\Hmac\Sha384 as HS384; -use Lcobucci\JWT\Signer\Hmac\Sha512 as HS512; -use Lcobucci\JWT\Signer\Keychain; +use DateTimeImmutable; +use DateTimeInterface; +use Lcobucci\JWT\Signer; use Lcobucci\JWT\Signer\Rsa; -use Lcobucci\JWT\Signer\Rsa\Sha256 as RS256; -use Lcobucci\JWT\Signer\Rsa\Sha384 as RS384; -use Lcobucci\JWT\Signer\Rsa\Sha512 as RS512; -use ReflectionClass; +use Lcobucci\JWT\Signer\Ecdsa; +use Lcobucci\JWT\Configuration; +use Lcobucci\JWT\Token\Builder; +use Illuminate\Support\Collection; +use Lcobucci\JWT\Signer\Key\InMemory; +use Lcobucci\JWT\Token\RegisteredClaims; use Tymon\JWTAuth\Contracts\Providers\JWT; use Tymon\JWTAuth\Exceptions\JWTException; +use Lcobucci\JWT\Validation\Constraint\SignedWith; use Tymon\JWTAuth\Exceptions\TokenInvalidException; class Lcobucci extends Provider implements JWT { /** - * The Builder instance. - * - * @var \Lcobucci\JWT\Builder + * \Lcobucci\JWT\Signer */ - protected $builder; + protected $signer; /** - * The Parser instance. - * - * @var \Lcobucci\JWT\Parser + * \Lcobucci\JWT\Configuration */ - protected $parser; + protected $config; /** * Create the Lcobucci provider. * - * @param \Lcobucci\JWT\Builder $builder - * @param \Lcobucci\JWT\Parser $parser * @param string $secret * @param string $algo * @param array $keys + * @param \Lcobucci\JWT\Configuration|null $config * * @return void */ - public function __construct( - Builder $builder, - Parser $parser, - $secret, - $algo, - array $keys - ) { + public function __construct($secret, $algo, array $keys, $config = null) + { parent::__construct($secret, $algo, $keys); - $this->builder = $builder; - $this->parser = $parser; $this->signer = $this->getSigner(); + $this->config = $config ?: $this->buildConfig(); } /** @@ -79,15 +63,15 @@ public function __construct( * @var array */ protected $signers = [ - 'HS256' => HS256::class, - 'HS384' => HS384::class, - 'HS512' => HS512::class, - 'RS256' => RS256::class, - 'RS384' => RS384::class, - 'RS512' => RS512::class, - 'ES256' => ES256::class, - 'ES384' => ES384::class, - 'ES512' => ES512::class, + self::ALGO_HS256 => Signer\Hmac\Sha256::class, + self::ALGO_HS384 => Signer\Hmac\Sha384::class, + self::ALGO_HS512 => Signer\Hmac\Sha512::class, + self::ALGO_RS256 => Signer\Rsa\Sha256::class, + self::ALGO_RS384 => Signer\Rsa\Sha384::class, + self::ALGO_RS512 => Signer\Rsa\Sha512::class, + self::ALGO_ES256 => Signer\Ecdsa\Sha256::class, + self::ALGO_ES384 => Signer\Ecdsa\Sha384::class, + self::ALGO_ES512 => Signer\Ecdsa\Sha512::class, ]; /** @@ -101,19 +85,15 @@ public function __construct( */ public function encode(array $payload) { - // Remove the signature on the builder instance first. - $this->builder->unsign(); + $builder = $this->getBuilderFromClaims($payload); try { - foreach ($payload as $key => $value) { - $this->builder->set($key, $value); - } - $this->builder->sign($this->signer, $this->getSigningKey()); + return $builder + ->getToken($this->config->signer(), $this->config->signingKey()) + ->toString(); } catch (Exception $e) { throw new JWTException('Could not create token: '.$e->getMessage(), $e->getCode(), $e); } - - return (string) $this->builder->getToken(); } /** @@ -128,18 +108,91 @@ public function encode(array $payload) public function decode($token) { try { - $jwt = $this->parser->parse($token); + /** @var \Lcobucci\JWT\Token\Plain */ + $token = $this->config->parser()->parse($token); } catch (Exception $e) { throw new TokenInvalidException('Could not decode token: '.$e->getMessage(), $e->getCode(), $e); } - if (! $jwt->verify($this->signer, $this->getVerificationKey())) { + if (! $this->config->validator()->validate($token, ...$this->config->validationConstraints())) { throw new TokenInvalidException('Token Signature could not be verified.'); } - return (new Collection($jwt->getClaims()))->map(function ($claim) { - return is_object($claim) ? $claim->getValue() : $claim; - })->toArray(); + return Collection::wrap($token->claims()->all()) + ->map(function ($claim) { + if ($claim instanceof DateTimeInterface) { + return $claim->getTimestamp(); + } + + return is_object($claim) && method_exists($claim, 'getValue') + ? $claim->getValue() + : $claim; + }) + ->toArray(); + } + + /** + * Create an instance of the builder with all of the claims applied. + * + * @param array $payload + * + * @return \Lcobucci\JWT\Token\Builder + */ + protected function getBuilderFromClaims(array $payload): Builder + { + $builder = $this->config->builder(); + + foreach ($payload as $key => $value) { + switch ($key) { + case RegisteredClaims::ID: + $builder->identifiedBy($value); + break; + case RegisteredClaims::EXPIRATION_TIME: + $builder->expiresAt(DateTimeImmutable::createFromFormat('U', $value)); + break; + case RegisteredClaims::NOT_BEFORE: + $builder->canOnlyBeUsedAfter(DateTimeImmutable::createFromFormat('U', $value)); + break; + case RegisteredClaims::ISSUED_AT: + $builder->issuedAt(DateTimeImmutable::createFromFormat('U', $value)); + break; + case RegisteredClaims::ISSUER: + $builder->issuedBy($value); + break; + case RegisteredClaims::AUDIENCE: + $builder->permittedFor($value); + break; + case RegisteredClaims::SUBJECT: + $builder->relatedTo($value); + break; + default: + $builder->withClaim($key, $value); + } + } + + return $builder; + } + + /** + * Build the configuration. + * + * @return \Lcobucci\JWT\Configuration + */ + protected function buildConfig(): Configuration + { + $config = $this->isAsymmetric() + ? Configuration::forAsymmetricSigner( + $this->signer, + $this->getSigningKey(), + $this->getVerificationKey() + ) + : Configuration::forSymmetricSigner($this->signer, $this->getSigningKey()); + + $config->setValidationConstraints( + new SignedWith($this->signer, $this->getVerificationKey()) + ); + + return $config; } /** @@ -155,7 +208,13 @@ protected function getSigner() throw new JWTException('The given algorithm could not be found'); } - return new $this->signers[$this->algo]; + $signer = $this->signers[$this->algo]; + + if (is_subclass_of($signer, Ecdsa::class)) { + return $signer::create(); + } + + return new $signer(); } /** @@ -163,28 +222,31 @@ protected function getSigner() */ protected function isAsymmetric() { - $reflect = new ReflectionClass($this->signer); - - return $reflect->isSubclassOf(Rsa::class) || $reflect->isSubclassOf(Ecdsa::class); + return is_subclass_of($this->signer, Rsa::class) + || is_subclass_of($this->signer, Ecdsa::class); } /** * {@inheritdoc} + * + * @return \Lcobucci\JWT\Signer\Key */ protected function getSigningKey() { - return $this->isAsymmetric() ? - (new Keychain())->getPrivateKey($this->getPrivateKey(), $this->getPassphrase()) : - $this->getSecret(); + return $this->isAsymmetric() + ? InMemory::plainText($this->getPrivateKey(), $this->getPassphrase() ?? '') + : InMemory::plainText($this->getSecret()); } /** * {@inheritdoc} + * + * @return \Lcobucci\JWT\Signer\Key */ protected function getVerificationKey() { - return $this->isAsymmetric() ? - (new Keychain())->getPublicKey($this->getPublicKey()) : - $this->getSecret(); + return $this->isAsymmetric() + ? InMemory::plainText($this->getPublicKey()) + : InMemory::plainText($this->getSecret()); } } diff --git a/src/Providers/JWT/Provider.php b/src/Providers/JWT/Provider.php index 2b08f71f0..2933e6b0d 100644 --- a/src/Providers/JWT/Provider.php +++ b/src/Providers/JWT/Provider.php @@ -15,6 +15,16 @@ abstract class Provider { + const ALGO_HS256 = 'HS256'; + const ALGO_HS384 = 'HS384'; + const ALGO_HS512 = 'HS512'; + const ALGO_RS256 = 'RS256'; + const ALGO_RS384 = 'RS384'; + const ALGO_RS512 = 'RS512'; + const ALGO_ES256 = 'ES256'; + const ALGO_ES384 = 'ES384'; + const ALGO_ES512 = 'ES512'; + /** * The secret. * @@ -115,8 +125,7 @@ public function setKeys(array $keys) } /** - * Get the array of keys used to sign tokens - * with an asymmetric algorithm. + * Get the array of keys used to sign tokens with an asymmetric algorithm. * * @return array */ @@ -126,10 +135,9 @@ public function getKeys() } /** - * Get the public key used to sign tokens - * with an asymmetric algorithm. + * Get the public key used to sign tokens with an asymmetric algorithm. * - * @return resource|string + * @return resource|string|null */ public function getPublicKey() { @@ -137,10 +145,9 @@ public function getPublicKey() } /** - * Get the private key used to sign tokens - * with an asymmetric algorithm. + * Get the private key used to sign tokens with an asymmetric algorithm. * - * @return resource|string + * @return resource|string|null */ public function getPrivateKey() { @@ -151,7 +158,7 @@ public function getPrivateKey() * Get the passphrase used to sign tokens * with an asymmetric algorithm. * - * @return string + * @return string|null */ public function getPassphrase() { @@ -161,7 +168,7 @@ public function getPassphrase() /** * Get the key used to sign the tokens. * - * @return resource|string + * @return resource|string|null */ protected function getSigningKey() { @@ -171,7 +178,7 @@ protected function getSigningKey() /** * Get the key used to verify the tokens. * - * @return resource|string + * @return resource|string|null */ protected function getVerificationKey() { @@ -179,10 +186,7 @@ protected function getVerificationKey() } /** - * Determine if the algorithm is asymmetric, and thus - * requires a public/private key combo. - * - * @throws \Tymon\JWTAuth\Exceptions\JWTException + * Determine if the algorithm is asymmetric, and thus requires a public/private key combo. * * @return bool */ diff --git a/tests/Providers/JWT/LcobucciTest.php b/tests/Providers/JWT/LcobucciTest.php index e3983023c..057cda8bd 100644 --- a/tests/Providers/JWT/LcobucciTest.php +++ b/tests/Providers/JWT/LcobucciTest.php @@ -11,82 +11,111 @@ namespace Tymon\JWTAuth\Test\Providers\JWT; -use Exception; -use InvalidArgumentException; -use Lcobucci\JWT\Builder; -use Lcobucci\JWT\Parser; -use Lcobucci\JWT\Signer\Key; -use Mockery; +use Tymon\JWTAuth\Test\AbstractTestCase; +use Tymon\JWTAuth\Providers\JWT\Lcobucci; +use Tymon\JWTAuth\Providers\JWT\Provider; use Tymon\JWTAuth\Exceptions\JWTException; use Tymon\JWTAuth\Exceptions\TokenInvalidException; -use Tymon\JWTAuth\Providers\JWT\Lcobucci; -use Tymon\JWTAuth\Test\AbstractTestCase; class LcobucciTest extends AbstractTestCase { - /** - * @var \Mockery\MockInterface - */ - protected $parser; - - /** - * @var \Mockery\MockInterface - */ - protected $builder; - - /** - * @var \Tymon\JWTAuth\Providers\JWT\Namshi - */ - protected $provider; - - public function setUp(): void + /** @test */ + public function it_can_encode_claims_using_a_symmetric_key() { - parent::setUp(); - - $this->builder = Mockery::mock(Builder::class); - $this->parser = Mockery::mock(Parser::class); + $payload = [ + 'sub' => 1, + 'exp' => $exp = $this->testNowTimestamp + 3600, + 'iat' => $iat = $this->testNowTimestamp, + 'iss' => '/foo', + 'custom_claim' => 'foobar', + ]; + + $token = $this->getProvider('secret', Provider::ALGO_HS256)->encode($payload); + [$header, $payload, $signature] = explode('.', $token); + + $claims = json_decode(base64_decode($payload), true); + $headerValues = json_decode(base64_decode($header), true); + + $this->assertEquals(Provider::ALGO_HS256, $headerValues['alg']); + $this->assertIsString($signature); + + $this->assertEquals('1', $claims['sub']); + $this->assertEquals('/foo', $claims['iss']); + $this->assertEquals('foobar', $claims['custom_claim']); + $this->assertEquals($exp, $claims['exp']); + $this->assertEquals($iat, $claims['iat']); } /** @test */ - public function it_should_return_the_token_when_passing_a_valid_payload_to_encode() + public function it_can_encode_and_decode_a_token_using_a_symmetric_key() { - $payload = ['sub' => 1, 'exp' => $this->testNowTimestamp + 3600, 'iat' => $this->testNowTimestamp, 'iss' => '/foo']; + $payload = [ + 'sub' => 1, + 'exp' => $exp = $this->testNowTimestamp + 3600, + 'iat' => $iat = $this->testNowTimestamp, + 'iss' => '/foo', + 'custom_claim' => 'foobar', + ]; - $this->builder->shouldReceive('unsign')->once()->andReturnSelf(); - $this->builder->shouldReceive('set')->times(count($payload)); - $this->builder->shouldReceive('sign')->once()->with(Mockery::any(), 'secret'); - $this->builder->shouldReceive('getToken')->once()->andReturn('foo.bar.baz'); + $provider = $this->getProvider('secret', Provider::ALGO_HS256); - $token = $this->getProvider('secret', 'HS256')->encode($payload); + $token = $provider->encode($payload); + $claims = $provider->decode($token); - $this->assertSame('foo.bar.baz', $token); + $this->assertEquals('1', $claims['sub']); + $this->assertEquals('/foo', $claims['iss']); + $this->assertEquals('foobar', $claims['custom_claim']); + $this->assertEquals($exp, $claims['exp']); + $this->assertEquals($iat, $claims['iat']); } /** @test */ - public function it_should_throw_an_invalid_exception_when_the_payload_could_not_be_encoded() + public function it_can_encode_and_decode_a_token_using_an_asymmetric_RS256_key() { - $this->expectException(JWTException::class); - $this->expectExceptionMessage('Could not create token:'); + $payload = [ + 'sub' => 1, + 'exp' => $exp = $this->testNowTimestamp + 3600, + 'iat' => $iat = $this->testNowTimestamp, + 'iss' => '/foo', + 'custom_claim' => 'foobar', + ]; - $payload = ['sub' => 1, 'exp' => $this->testNowTimestamp, 'iat' => $this->testNowTimestamp, 'iss' => '/foo']; + $provider = $this->getProvider( + 'secret', + Provider::ALGO_RS256, + ['private' => $this->getDummyPrivateKey(), 'public' => $this->getDummyPublicKey()] + ); + + $token = $provider->encode($payload); - $this->builder->shouldReceive('unsign')->once()->andReturnSelf(); - $this->builder->shouldReceive('set')->times(count($payload)); - $this->builder->shouldReceive('sign')->once()->with(Mockery::any(), 'secret')->andThrow(new Exception); + $header = json_decode(base64_decode(head(explode('.', $token))), true); + $this->assertEquals(Provider::ALGO_RS256, $header['alg']); - $this->getProvider('secret', 'HS256')->encode($payload); + $claims = $provider->decode($token); + + $this->assertEquals('1', $claims['sub']); + $this->assertEquals('/foo', $claims['iss']); + $this->assertEquals('foobar', $claims['custom_claim']); + $this->assertEquals($exp, $claims['exp']); + $this->assertEquals($iat, $claims['iat']); } /** @test */ - public function it_should_return_the_payload_when_passing_a_valid_token_to_decode() + public function it_should_throw_an_invalid_exception_when_the_payload_could_not_be_encoded() { - $payload = ['sub' => 1, 'exp' => $this->testNowTimestamp + 3600, 'iat' => $this->testNowTimestamp, 'iss' => '/foo']; + $this->expectException(JWTException::class); + $this->expectExceptionMessage('Could not create token:'); - $this->parser->shouldReceive('parse')->once()->with('foo.bar.baz')->andReturn(Mockery::self()); - $this->parser->shouldReceive('verify')->once()->with(Mockery::any(), 'secret')->andReturn(true); - $this->parser->shouldReceive('getClaims')->once()->andReturn($payload); + $payload = [ + 'sub' => 1, + 'exp' => $this->testNowTimestamp + 3600, + 'iat' => $this->testNowTimestamp, + 'iss' => '/foo', + 'custom_claim' => 'foobar', + 'invalid_utf8' => "\xB1\x31", // cannot be encoded as JSON + ]; - $this->assertSame($payload, $this->getProvider('secret', 'HS256')->decode('foo.bar.baz')); + $this->getProvider('secret', Provider::ALGO_HS256)->encode($payload); } /** @test */ @@ -95,45 +124,29 @@ public function it_should_throw_a_token_invalid_exception_when_the_token_could_n $this->expectException(TokenInvalidException::class); $this->expectExceptionMessage('Token Signature could not be verified.'); - $this->parser->shouldReceive('parse')->once()->with('foo.bar.baz')->andReturn(Mockery::self()); - $this->parser->shouldReceive('verify')->once()->with(Mockery::any(), 'secret')->andReturn(false); - $this->parser->shouldReceive('getClaims')->never(); - - $this->getProvider('secret', 'HS256')->decode('foo.bar.baz'); + // This has a different secret than the one used to encode the token + $this->getProvider('secret', Provider::ALGO_HS256) + ->decode('eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwiZXhwIjoxNjQ5MjYxMDY1LCJpYXQiOjE2NDkyNTc0NjUsImlzcyI6Ii9mb28iLCJjdXN0b21fY2xhaW0iOiJmb29iYXIifQ.jZufNqDHAxtboUIPmDp4ZFOIQxK-B5G6vNdBEp-9uL8'); } /** @test */ - public function it_should_throw_a_token_invalid_exception_when_the_token_could_not_be_decoded() + public function it_should_throw_a_token_invalid_exception_when_the_token_could_not_be_decoded_due_to_tampered_token() { $this->expectException(TokenInvalidException::class); - $this->expectExceptionMessage('Could not decode token:'); - - $this->parser->shouldReceive('parse')->once()->with('foo.bar.baz')->andThrow(new InvalidArgumentException); - $this->parser->shouldReceive('verify')->never(); - $this->parser->shouldReceive('getClaims')->never(); + $this->expectExceptionMessage('Token Signature could not be verified.'); - $this->getProvider('secret', 'HS256')->decode('foo.bar.baz'); + // This sub claim for this token has been tampered with so the signature will not match + $this->getProvider('secret', Provider::ALGO_HS256) + ->decode('eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIyIiwiZXhwIjoxNjQ5MjY0OTA2LCJpYXQiOjE2NDkyNjEzMDYsImlzcyI6Ii9mb28iLCJjdXN0b21fY2xhaW0iOiJmb29iYXIifQ.IcJvMvwMXf8oEpnz8-hvAy60QDE_o8XFaxhbZIGVy0U'); } /** @test */ - public function it_should_generate_a_token_when_using_an_rsa_algorithm() + public function it_should_throw_a_token_invalid_exception_when_the_token_could_not_be_decoded() { - $provider = $this->getProvider( - 'does_not_matter', - 'RS256', - ['private' => $this->getDummyPrivateKey(), 'public' => $this->getDummyPublicKey()] - ); - - $payload = ['sub' => 1, 'exp' => $this->testNowTimestamp + 3600, 'iat' => $this->testNowTimestamp, 'iss' => '/foo']; - - $this->builder->shouldReceive('unsign')->once()->andReturnSelf(); - $this->builder->shouldReceive('set')->times(count($payload)); - $this->builder->shouldReceive('sign')->once()->with(Mockery::any(), Mockery::type(Key::class)); - $this->builder->shouldReceive('getToken')->once()->andReturn('foo.bar.baz'); - - $token = $provider->encode($payload); + $this->expectException(TokenInvalidException::class); + $this->expectExceptionMessage('Could not decode token:'); - $this->assertSame('foo.bar.baz', $token); + $this->getProvider('secret', 'HS256')->decode('foo.bar.baz'); } /** @test */ @@ -142,10 +155,7 @@ public function it_should_throw_a_exception_when_the_algorithm_passed_is_invalid $this->expectException(JWTException::class); $this->expectExceptionMessage('The given algorithm could not be found'); - $this->parser->shouldReceive('parse')->never(); - $this->parser->shouldReceive('verify')->never(); - - $this->getProvider('secret', 'AlgorithmWrong')->decode('foo.bar.baz'); + $this->getProvider('secret', 'INVALID_ALGO')->decode('foo.bar.baz'); } /** @test */ @@ -174,7 +184,7 @@ public function it_should_return_the_keys() public function getProvider($secret, $algo, array $keys = []) { - return new Lcobucci($this->builder, $this->parser, $secret, $algo, $keys); + return new Lcobucci($secret, $algo, $keys); } public function getDummyPrivateKey() From 60a030a5249efb4f595fe88d922461871fcfe404 Mon Sep 17 00:00:00 2001 From: Sean Tymon Date: Thu, 7 Apr 2022 09:16:48 +0000 Subject: [PATCH 02/10] fix: StyleCI --- .styleci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.styleci.yml b/.styleci.yml index 1bb05494a..2aaa94ab5 100644 --- a/.styleci.yml +++ b/.styleci.yml @@ -2,7 +2,5 @@ preset: laravel enabled: - no_useless_else - - phpdoc_order - phpdoc_separation - unalign_double_arrow - # - length_ordered_imports From 3ffeec450981a3e3c7c2e271417ec3644fb0af74 Mon Sep 17 00:00:00 2001 From: Sean Tymon Date: Thu, 7 Apr 2022 09:17:44 +0000 Subject: [PATCH 03/10] fix: StyleCI --- .styleci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.styleci.yml b/.styleci.yml index 2aaa94ab5..cc5f07ab5 100644 --- a/.styleci.yml +++ b/.styleci.yml @@ -2,5 +2,4 @@ preset: laravel enabled: - no_useless_else - - phpdoc_separation - unalign_double_arrow From 4002b777ac5bd2b5a9eddb970a024b9998986937 Mon Sep 17 00:00:00 2001 From: Sean Tymon Date: Thu, 7 Apr 2022 10:18:03 +0100 Subject: [PATCH 04/10] Apply fixes from StyleCI (#2176) [ci skip] [skip ci] --- src/Blacklist.php | 10 ------- src/Claims/Claim.php | 9 +----- src/Claims/Collection.php | 5 ---- src/Claims/Custom.php | 1 - src/Claims/DatetimeTrait.php | 6 +--- src/Claims/Factory.php | 8 ------ src/Console/JWTGenerateSecretCommand.php | 1 - src/Contracts/Claim.php | 5 +--- src/Contracts/Http/Parser.php | 1 - src/Contracts/Providers/Auth.php | 2 -- src/Contracts/Providers/JWT.php | 2 -- src/Contracts/Providers/Storage.php | 4 --- src/Contracts/Validator.php | 2 -- src/Exceptions/InvalidClaimException.php | 1 - src/Factory.php | 8 ------ src/Http/Middleware/Authenticate.php | 3 +- src/Http/Middleware/AuthenticateAndRenew.php | 3 +- src/Http/Middleware/BaseMiddleware.php | 8 ++---- src/Http/Middleware/Check.php | 1 - src/Http/Middleware/RefreshToken.php | 3 +- src/Http/Parser/AuthHeaders.php | 4 --- src/Http/Parser/Cookies.php | 1 - src/Http/Parser/InputSource.php | 1 - src/Http/Parser/KeyTrait.php | 1 - src/Http/Parser/LumenRouteParams.php | 1 - src/Http/Parser/Parser.php | 7 +---- src/Http/Parser/QueryString.php | 1 - src/Http/Parser/RouteParams.php | 1 - src/JWT.php | 30 +++++--------------- src/JWTAuth.php | 2 -- src/JWTGuard.php | 30 ++++---------------- src/Manager.php | 12 ++------ src/Payload.php | 17 ++--------- src/Providers/AbstractServiceProvider.php | 2 -- src/Providers/Auth/Illuminate.php | 3 -- src/Providers/JWT/Lcobucci.php | 28 ++++++++---------- src/Providers/JWT/Namshi.php | 7 ++--- src/Providers/JWT/Provider.php | 4 --- src/Providers/Storage/Illuminate.php | 5 ---- src/Support/CustomClaims.php | 2 -- src/Support/RefreshFlow.php | 1 - src/Support/Utils.php | 3 -- src/Token.php | 1 - src/Validators/PayloadValidator.php | 12 ++------ src/Validators/TokenValidator.php | 4 +-- src/Validators/Validator.php | 2 -- tests/BlacklistTest.php | 2 +- tests/PayloadTest.php | 1 - tests/Providers/JWT/LcobucciTest.php | 6 ++-- 49 files changed, 48 insertions(+), 226 deletions(-) diff --git a/src/Blacklist.php b/src/Blacklist.php index 5a3f546de..ba12405be 100644 --- a/src/Blacklist.php +++ b/src/Blacklist.php @@ -48,7 +48,6 @@ class Blacklist * Constructor. * * @param \Tymon\JWTAuth\Contracts\Providers\Storage $storage - * * @return void */ public function __construct(Storage $storage) @@ -60,7 +59,6 @@ public function __construct(Storage $storage) * Add the token (jti claim) to the blacklist. * * @param \Tymon\JWTAuth\Payload $payload - * * @return bool */ public function add(Payload $payload) @@ -89,7 +87,6 @@ public function add(Payload $payload) * Get the number of minutes until the token expiry. * * @param \Tymon\JWTAuth\Payload $payload - * * @return int */ protected function getMinutesUntilExpired(Payload $payload) @@ -107,7 +104,6 @@ protected function getMinutesUntilExpired(Payload $payload) * Add the token (jti claim) to the blacklist indefinitely. * * @param \Tymon\JWTAuth\Payload $payload - * * @return bool */ public function addForever(Payload $payload) @@ -121,7 +117,6 @@ public function addForever(Payload $payload) * Determine whether the token has been blacklisted. * * @param \Tymon\JWTAuth\Payload $payload - * * @return bool */ public function has(Payload $payload) @@ -141,7 +136,6 @@ public function has(Payload $payload) * Remove the token (jti claim) from the blacklist. * * @param \Tymon\JWTAuth\Payload $payload - * * @return bool */ public function remove(Payload $payload) @@ -176,7 +170,6 @@ protected function getGraceTimestamp() * Set the grace period. * * @param int $gracePeriod - * * @return $this */ public function setGracePeriod($gracePeriod) @@ -200,7 +193,6 @@ public function getGracePeriod() * Get the unique key held within the blacklist. * * @param \Tymon\JWTAuth\Payload $payload - * * @return mixed */ public function getKey(Payload $payload) @@ -212,7 +204,6 @@ public function getKey(Payload $payload) * Set the unique key held within the blacklist. * * @param string $key - * * @return $this */ public function setKey($key) @@ -226,7 +217,6 @@ public function setKey($key) * Set the refresh time limit. * * @param int $ttl - * * @return $this */ public function setRefreshTTL($ttl) diff --git a/src/Claims/Claim.php b/src/Claims/Claim.php index d1721fbfd..c44ebcf8a 100644 --- a/src/Claims/Claim.php +++ b/src/Claims/Claim.php @@ -34,7 +34,6 @@ abstract class Claim implements Arrayable, ClaimContract, Jsonable, JsonSerializ /** * @param mixed $value - * * @return void */ public function __construct($value) @@ -46,10 +45,9 @@ public function __construct($value) * Set the claim value, and call a validate method. * * @param mixed $value + * @return $this * * @throws \Tymon\JWTAuth\Exceptions\InvalidClaimException - * - * @return $this */ public function setValue($value) { @@ -72,7 +70,6 @@ public function getValue() * Set the claim name. * * @param string $name - * * @return $this */ public function setName($name) @@ -96,7 +93,6 @@ public function getName() * Validate the claim in a standalone Claim context. * * @param mixed $value - * * @return bool */ public function validateCreate($value) @@ -118,7 +114,6 @@ public function validatePayload() * Validate the Claim within a refresh context. * * @param int $refreshTTL - * * @return bool */ public function validateRefresh($refreshTTL) @@ -131,7 +126,6 @@ public function validateRefresh($refreshTTL) * * @param mixed $value * @param bool $strict - * * @return bool */ public function matches($value, $strict = true) @@ -163,7 +157,6 @@ public function toArray() * Get the claim as JSON. * * @param int $options - * * @return string */ public function toJson($options = JSON_UNESCAPED_SLASHES) diff --git a/src/Claims/Collection.php b/src/Claims/Collection.php index 3199dca70..bdade308a 100644 --- a/src/Claims/Collection.php +++ b/src/Claims/Collection.php @@ -20,7 +20,6 @@ class Collection extends IlluminateCollection * Create a new collection. * * @param mixed $items - * * @return void */ public function __construct($items = []) @@ -34,7 +33,6 @@ public function __construct($items = []) * @param string $name * @param callable $callback * @param mixed $default - * * @return \Tymon\JWTAuth\Claims\Claim */ public function getByClaimName($name, callable $callback = null, $default = null) @@ -48,7 +46,6 @@ public function getByClaimName($name, callable $callback = null, $default = null * Validate each claim under a given context. * * @param string $context - * * @return $this */ public function validate($context = 'payload') @@ -70,7 +67,6 @@ public function validate($context = 'payload') * Determine if the Collection contains all of the given keys. * * @param mixed $claims - * * @return bool */ public function hasAllClaims($claims) @@ -102,7 +98,6 @@ protected function getArrayableItems($items) * Ensure that the given claims array is keyed by the claim name. * * @param mixed $items - * * @return array */ private function sanitizeClaims($items) diff --git a/src/Claims/Custom.php b/src/Claims/Custom.php index 0e43de54f..d01e535bb 100644 --- a/src/Claims/Custom.php +++ b/src/Claims/Custom.php @@ -16,7 +16,6 @@ class Custom extends Claim /** * @param string $name * @param mixed $value - * * @return void */ public function __construct($name, $value) diff --git a/src/Claims/DatetimeTrait.php b/src/Claims/DatetimeTrait.php index dbda1e3c9..804f06786 100644 --- a/src/Claims/DatetimeTrait.php +++ b/src/Claims/DatetimeTrait.php @@ -29,10 +29,9 @@ trait DatetimeTrait * Set the claim value, and call a validate method. * * @param mixed $value + * @return $this * * @throws \Tymon\JWTAuth\Exceptions\InvalidClaimException - * - * @return $this */ public function setValue($value) { @@ -63,7 +62,6 @@ public function validateCreate($value) * Determine whether the value is in the future. * * @param mixed $value - * * @return bool */ protected function isFuture($value) @@ -75,7 +73,6 @@ protected function isFuture($value) * Determine whether the value is in the past. * * @param mixed $value - * * @return bool */ protected function isPast($value) @@ -87,7 +84,6 @@ protected function isPast($value) * Set the leeway in seconds. * * @param int $leeway - * * @return $this */ public function setLeeway($leeway) diff --git a/src/Claims/Factory.php b/src/Claims/Factory.php index 0fc6fa6de..9985ddc8d 100644 --- a/src/Claims/Factory.php +++ b/src/Claims/Factory.php @@ -57,7 +57,6 @@ class Factory * Constructor. * * @param \Illuminate\Http\Request $request - * * @return void */ public function __construct(Request $request) @@ -70,7 +69,6 @@ public function __construct(Request $request) * * @param string $name * @param mixed $value - * * @return \Tymon\JWTAuth\Claims\Claim */ public function get($name, $value) @@ -90,7 +88,6 @@ public function get($name, $value) * Check whether the claim exists. * * @param string $name - * * @return bool */ public function has($name) @@ -102,7 +99,6 @@ public function has($name) * Generate the initial value and return the Claim instance. * * @param string $name - * * @return \Tymon\JWTAuth\Claims\Claim */ public function make($name) @@ -165,7 +161,6 @@ public function jti() * * @param string $name * @param string $classPath - * * @return $this */ public function extend($name, $classPath) @@ -179,7 +174,6 @@ public function extend($name, $classPath) * Set the request instance. * * @param \Illuminate\Http\Request $request - * * @return $this */ public function setRequest(Request $request) @@ -193,7 +187,6 @@ public function setRequest(Request $request) * Set the token ttl (in minutes). * * @param int $ttl - * * @return $this */ public function setTTL($ttl) @@ -217,7 +210,6 @@ public function getTTL() * Set the leeway in seconds. * * @param int $leeway - * * @return $this */ public function setLeeway($leeway) diff --git a/src/Console/JWTGenerateSecretCommand.php b/src/Console/JWTGenerateSecretCommand.php index 93f916479..7c6e6d73e 100644 --- a/src/Console/JWTGenerateSecretCommand.php +++ b/src/Console/JWTGenerateSecretCommand.php @@ -82,7 +82,6 @@ public function handle() * Display the key. * * @param string $key - * * @return void */ protected function displayKey($key) diff --git a/src/Contracts/Claim.php b/src/Contracts/Claim.php index 9d6e9a94e..46e49cecc 100644 --- a/src/Contracts/Claim.php +++ b/src/Contracts/Claim.php @@ -17,10 +17,9 @@ interface Claim * Set the claim value, and call a validate method. * * @param mixed $value + * @return $this * * @throws \Tymon\JWTAuth\Exceptions\InvalidClaimException - * - * @return $this */ public function setValue($value); @@ -35,7 +34,6 @@ public function getValue(); * Set the claim name. * * @param string $name - * * @return $this */ public function setName($name); @@ -51,7 +49,6 @@ public function getName(); * Validate the Claim value. * * @param mixed $value - * * @return bool */ public function validateCreate($value); diff --git a/src/Contracts/Http/Parser.php b/src/Contracts/Http/Parser.php index c1faa3333..8612b90ef 100644 --- a/src/Contracts/Http/Parser.php +++ b/src/Contracts/Http/Parser.php @@ -19,7 +19,6 @@ interface Parser * Parse the request. * * @param \Illuminate\Http\Request $request - * * @return null|string */ public function parse(Request $request); diff --git a/src/Contracts/Providers/Auth.php b/src/Contracts/Providers/Auth.php index 553d4021e..d71c77497 100644 --- a/src/Contracts/Providers/Auth.php +++ b/src/Contracts/Providers/Auth.php @@ -17,7 +17,6 @@ interface Auth * Check a user's credentials. * * @param array $credentials - * * @return mixed */ public function byCredentials(array $credentials); @@ -26,7 +25,6 @@ public function byCredentials(array $credentials); * Authenticate a user via the id. * * @param mixed $id - * * @return mixed */ public function byId($id); diff --git a/src/Contracts/Providers/JWT.php b/src/Contracts/Providers/JWT.php index 7065a8791..b71d6310e 100644 --- a/src/Contracts/Providers/JWT.php +++ b/src/Contracts/Providers/JWT.php @@ -15,14 +15,12 @@ interface JWT { /** * @param array $payload - * * @return string */ public function encode(array $payload); /** * @param string $token - * * @return array */ public function decode($token); diff --git a/src/Contracts/Providers/Storage.php b/src/Contracts/Providers/Storage.php index 5a0ed6d85..a60c92853 100644 --- a/src/Contracts/Providers/Storage.php +++ b/src/Contracts/Providers/Storage.php @@ -17,7 +17,6 @@ interface Storage * @param string $key * @param mixed $value * @param int $minutes - * * @return void */ public function add($key, $value, $minutes); @@ -25,21 +24,18 @@ public function add($key, $value, $minutes); /** * @param string $key * @param mixed $value - * * @return void */ public function forever($key, $value); /** * @param string $key - * * @return mixed */ public function get($key); /** * @param string $key - * * @return bool */ public function destroy($key); diff --git a/src/Contracts/Validator.php b/src/Contracts/Validator.php index c9ae3de0f..664febccd 100644 --- a/src/Contracts/Validator.php +++ b/src/Contracts/Validator.php @@ -17,7 +17,6 @@ interface Validator * Perform some checks on the value. * * @param mixed $value - * * @return void */ public function check($value); @@ -26,7 +25,6 @@ public function check($value); * Helper function to return a boolean. * * @param array $value - * * @return bool */ public function isValid($value); diff --git a/src/Exceptions/InvalidClaimException.php b/src/Exceptions/InvalidClaimException.php index 7a17feb72..3c2df7b7e 100644 --- a/src/Exceptions/InvalidClaimException.php +++ b/src/Exceptions/InvalidClaimException.php @@ -22,7 +22,6 @@ class InvalidClaimException extends JWTException * @param \Tymon\JWTAuth\Claims\Claim $claim * @param int $code * @param \Exception|null $previous - * * @return void */ public function __construct(Claim $claim, $code = 0, Exception $previous = null) diff --git a/src/Factory.php b/src/Factory.php index e25c1979e..f7b4c097a 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -61,7 +61,6 @@ class Factory * * @param \Tymon\JWTAuth\Claims\Factory $claimFactory * @param \Tymon\JWTAuth\Validators\PayloadValidator $validator - * * @return void */ public function __construct(ClaimFactory $claimFactory, PayloadValidator $validator) @@ -75,7 +74,6 @@ public function __construct(ClaimFactory $claimFactory, PayloadValidator $valida * Create the Payload instance. * * @param bool $resetClaims - * * @return \Tymon\JWTAuth\Payload */ public function make($resetClaims = false) @@ -103,7 +101,6 @@ public function emptyClaims() * Add an array of claims to the Payload. * * @param array $claims - * * @return $this */ protected function addClaims(array $claims) @@ -120,7 +117,6 @@ protected function addClaims(array $claims) * * @param string $name * @param mixed $value - * * @return $this */ protected function addClaim($name, $value) @@ -177,7 +173,6 @@ public function buildClaimsCollection() * Get a Payload instance with a claims collection. * * @param \Tymon\JWTAuth\Claims\Collection $claims - * * @return \Tymon\JWTAuth\Payload */ public function withClaims(Collection $claims) @@ -189,7 +184,6 @@ public function withClaims(Collection $claims) * Set the default claims to be added to the Payload. * * @param array $claims - * * @return $this */ public function setDefaultClaims(array $claims) @@ -203,7 +197,6 @@ public function setDefaultClaims(array $claims) * Helper to set the ttl. * * @param int $ttl - * * @return $this */ public function setTTL($ttl) @@ -248,7 +241,6 @@ public function validator() * * @param string $method * @param array $parameters - * * @return $this */ public function __call($method, $parameters) diff --git a/src/Http/Middleware/Authenticate.php b/src/Http/Middleware/Authenticate.php index 257839b08..f9e62b234 100644 --- a/src/Http/Middleware/Authenticate.php +++ b/src/Http/Middleware/Authenticate.php @@ -21,10 +21,9 @@ class Authenticate extends BaseMiddleware * * @param \Illuminate\Http\Request $request * @param \Closure $next + * @return mixed * * @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException - * - * @return mixed */ public function handle($request, Closure $next) { diff --git a/src/Http/Middleware/AuthenticateAndRenew.php b/src/Http/Middleware/AuthenticateAndRenew.php index 7f6ba58c8..60bfed90e 100644 --- a/src/Http/Middleware/AuthenticateAndRenew.php +++ b/src/Http/Middleware/AuthenticateAndRenew.php @@ -21,10 +21,9 @@ class AuthenticateAndRenew extends BaseMiddleware * * @param \Illuminate\Http\Request $request * @param \Closure $next + * @return mixed * * @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException - * - * @return mixed */ public function handle($request, Closure $next) { diff --git a/src/Http/Middleware/BaseMiddleware.php b/src/Http/Middleware/BaseMiddleware.php index c977d4e10..50a89a44d 100644 --- a/src/Http/Middleware/BaseMiddleware.php +++ b/src/Http/Middleware/BaseMiddleware.php @@ -30,7 +30,6 @@ abstract class BaseMiddleware * Create a new BaseMiddleware instance. * * @param \Tymon\JWTAuth\JWTAuth $auth - * * @return void */ public function __construct(JWTAuth $auth) @@ -42,10 +41,9 @@ public function __construct(JWTAuth $auth) * Check the request for the presence of a token. * * @param \Illuminate\Http\Request $request + * @return void * * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException - * - * @return void */ public function checkForToken(Request $request) { @@ -58,10 +56,9 @@ public function checkForToken(Request $request) * Attempt to authenticate a user via the token in the request. * * @param \Illuminate\Http\Request $request + * @return void * * @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException - * - * @return void */ public function authenticate(Request $request) { @@ -81,7 +78,6 @@ public function authenticate(Request $request) * * @param \Illuminate\Http\Response|\Illuminate\Http\JsonResponse $response * @param string|null $token - * * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse */ protected function setAuthenticationHeader($response, $token = null) diff --git a/src/Http/Middleware/Check.php b/src/Http/Middleware/Check.php index ae249c3a6..3d64913de 100644 --- a/src/Http/Middleware/Check.php +++ b/src/Http/Middleware/Check.php @@ -22,7 +22,6 @@ class Check extends BaseMiddleware * * @param \Illuminate\Http\Request $request * @param \Closure $next - * * @return mixed */ public function handle($request, Closure $next) diff --git a/src/Http/Middleware/RefreshToken.php b/src/Http/Middleware/RefreshToken.php index f3eefa7a8..f053ef2ff 100644 --- a/src/Http/Middleware/RefreshToken.php +++ b/src/Http/Middleware/RefreshToken.php @@ -23,10 +23,9 @@ class RefreshToken extends BaseMiddleware * * @param \Illuminate\Http\Request $request * @param \Closure $next + * @return mixed * * @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException - * - * @return mixed */ public function handle($request, Closure $next) { diff --git a/src/Http/Parser/AuthHeaders.php b/src/Http/Parser/AuthHeaders.php index 40d2d5a64..da454e2e4 100644 --- a/src/Http/Parser/AuthHeaders.php +++ b/src/Http/Parser/AuthHeaders.php @@ -34,7 +34,6 @@ class AuthHeaders implements ParserContract * Attempt to parse the token from some other possible headers. * * @param \Illuminate\Http\Request $request - * * @return null|string */ protected function fromAltHeaders(Request $request) @@ -46,7 +45,6 @@ protected function fromAltHeaders(Request $request) * Try to parse the token from the request header. * * @param \Illuminate\Http\Request $request - * * @return null|string */ public function parse(Request $request) @@ -64,7 +62,6 @@ public function parse(Request $request) * Set the header name. * * @param string $headerName - * * @return $this */ public function setHeaderName($headerName) @@ -78,7 +75,6 @@ public function setHeaderName($headerName) * Set the header prefix. * * @param string $headerPrefix - * * @return $this */ public function setHeaderPrefix($headerPrefix) diff --git a/src/Http/Parser/Cookies.php b/src/Http/Parser/Cookies.php index ad3d5e211..dab486b70 100644 --- a/src/Http/Parser/Cookies.php +++ b/src/Http/Parser/Cookies.php @@ -35,7 +35,6 @@ public function __construct($decrypt = true) * Try to parse the token from the request cookies. * * @param \Illuminate\Http\Request $request - * * @return null|string */ public function parse(Request $request) diff --git a/src/Http/Parser/InputSource.php b/src/Http/Parser/InputSource.php index d5692bf0c..9c618db5a 100644 --- a/src/Http/Parser/InputSource.php +++ b/src/Http/Parser/InputSource.php @@ -22,7 +22,6 @@ class InputSource implements ParserContract * Try to parse the token from the request input source. * * @param \Illuminate\Http\Request $request - * * @return null|string */ public function parse(Request $request) diff --git a/src/Http/Parser/KeyTrait.php b/src/Http/Parser/KeyTrait.php index e65da38e6..4f71e0205 100644 --- a/src/Http/Parser/KeyTrait.php +++ b/src/Http/Parser/KeyTrait.php @@ -24,7 +24,6 @@ trait KeyTrait * Set the key. * * @param string $key - * * @return $this */ public function setKey($key) diff --git a/src/Http/Parser/LumenRouteParams.php b/src/Http/Parser/LumenRouteParams.php index e9a7b7a4f..5b7eac208 100644 --- a/src/Http/Parser/LumenRouteParams.php +++ b/src/Http/Parser/LumenRouteParams.php @@ -20,7 +20,6 @@ class LumenRouteParams extends RouteParams * Try to get the token from the route parameters. * * @param \Illuminate\Http\Request $request - * * @return null|string */ public function parse(Request $request) diff --git a/src/Http/Parser/Parser.php b/src/Http/Parser/Parser.php index 4c1881931..23f09a2d8 100644 --- a/src/Http/Parser/Parser.php +++ b/src/Http/Parser/Parser.php @@ -34,7 +34,6 @@ class Parser * * @param \Illuminate\Http\Request $request * @param array $chain - * * @return void */ public function __construct(Request $request, array $chain = []) @@ -56,8 +55,7 @@ public function getChain() /** * Add a new parser to the chain. * - * @param array|\Tymon\JWTAuth\Contracts\Http\Parser $parsers - * + * @param array|\Tymon\JWTAuth\Contracts\Http\Parser $parsers * @return $this */ public function addParser($parsers) @@ -71,7 +69,6 @@ public function addParser($parsers) * Set the order of the parser chain. * * @param array $chain - * * @return $this */ public function setChain(array $chain) @@ -85,7 +82,6 @@ public function setChain(array $chain) * Alias for setting the order of the chain. * * @param array $chain - * * @return $this */ public function setChainOrder(array $chain) @@ -122,7 +118,6 @@ public function hasToken() * Set the request instance. * * @param \Illuminate\Http\Request $request - * * @return $this */ public function setRequest(Request $request) diff --git a/src/Http/Parser/QueryString.php b/src/Http/Parser/QueryString.php index 68b1a3594..c801a8216 100644 --- a/src/Http/Parser/QueryString.php +++ b/src/Http/Parser/QueryString.php @@ -22,7 +22,6 @@ class QueryString implements ParserContract * Try to parse the token from the request query string. * * @param \Illuminate\Http\Request $request - * * @return null|string */ public function parse(Request $request) diff --git a/src/Http/Parser/RouteParams.php b/src/Http/Parser/RouteParams.php index b178b238a..a40aba8b4 100644 --- a/src/Http/Parser/RouteParams.php +++ b/src/Http/Parser/RouteParams.php @@ -22,7 +22,6 @@ class RouteParams implements ParserContract * Try to get the token from the route parameters. * * @param \Illuminate\Http\Request $request - * * @return null|string */ public function parse(Request $request) diff --git a/src/JWT.php b/src/JWT.php index c881009cd..a958071ce 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -55,7 +55,6 @@ class JWT * * @param \Tymon\JWTAuth\Manager $manager * @param \Tymon\JWTAuth\Http\Parser\Parser $parser - * * @return void */ public function __construct(Manager $manager, Parser $parser) @@ -68,7 +67,6 @@ public function __construct(Manager $manager, Parser $parser) * Generate a token for a given subject. * * @param \Tymon\JWTAuth\Contracts\JWTSubject $subject - * * @return string */ public function fromSubject(JWTSubject $subject) @@ -82,7 +80,6 @@ public function fromSubject(JWTSubject $subject) * Alias to generate a token for a given user. * * @param \Tymon\JWTAuth\Contracts\JWTSubject $user - * * @return string */ public function fromUser(JWTSubject $user) @@ -95,7 +92,6 @@ public function fromUser(JWTSubject $user) * * @param bool $forceForever * @param bool $resetClaims - * * @return string */ public function refresh($forceForever = false, $resetClaims = false) @@ -111,7 +107,6 @@ public function refresh($forceForever = false, $resetClaims = false) * Invalidate a token (add it to the blacklist). * * @param bool $forceForever - * * @return $this */ public function invalidate($forceForever = false) @@ -127,9 +122,9 @@ public function invalidate($forceForever = false) * Alias to get the payload, and as a result checks that * the token is valid i.e. not expired or blacklisted. * - * @throws \Tymon\JWTAuth\Exceptions\JWTException - * * @return \Tymon\JWTAuth\Payload + * + * @throws \Tymon\JWTAuth\Exceptions\JWTException */ public function checkOrFail() { @@ -140,7 +135,6 @@ public function checkOrFail() * Check that the token is valid. * * @param bool $getPayload - * * @return \Tymon\JWTAuth\Payload|bool */ public function check($getPayload = false) @@ -175,9 +169,9 @@ public function getToken() /** * Parse the token from the request. * - * @throws \Tymon\JWTAuth\Exceptions\JWTException - * * @return $this + * + * @throws \Tymon\JWTAuth\Exceptions\JWTException */ public function parseToken() { @@ -214,7 +208,6 @@ public function payload() * Convenience method to get a claim value. * * @param string $claim - * * @return mixed */ public function getClaim($claim) @@ -226,7 +219,6 @@ public function getClaim($claim) * Create a Payload instance. * * @param \Tymon\JWTAuth\Contracts\JWTSubject $subject - * * @return \Tymon\JWTAuth\Payload */ public function makePayload(JWTSubject $subject) @@ -238,7 +230,6 @@ public function makePayload(JWTSubject $subject) * Build the claims array and return it. * * @param \Tymon\JWTAuth\Contracts\JWTSubject $subject - * * @return array */ protected function getClaimsArray(JWTSubject $subject) @@ -254,7 +245,6 @@ protected function getClaimsArray(JWTSubject $subject) * Get the claims associated with a given subject. * * @param \Tymon\JWTAuth\Contracts\JWTSubject $subject - * * @return array */ protected function getClaimsForSubject(JWTSubject $subject) @@ -268,7 +258,6 @@ protected function getClaimsForSubject(JWTSubject $subject) * Hash the subject model and return it. * * @param string|object $model - * * @return string */ protected function hashSubjectModel($model) @@ -280,7 +269,6 @@ protected function hashSubjectModel($model) * Check if the subject model matches the one saved in the token. * * @param string|object $model - * * @return bool */ public function checkSubjectModel($model) @@ -296,7 +284,6 @@ public function checkSubjectModel($model) * Set the token. * * @param \Tymon\JWTAuth\Token|string $token - * * @return $this */ public function setToken($token) @@ -321,9 +308,9 @@ public function unsetToken() /** * Ensure that a token is available. * - * @throws \Tymon\JWTAuth\Exceptions\JWTException - * * @return void + * + * @throws \Tymon\JWTAuth\Exceptions\JWTException */ protected function requireToken() { @@ -336,7 +323,6 @@ protected function requireToken() * Set the request instance. * * @param \Illuminate\Http\Request $request - * * @return $this */ public function setRequest(Request $request) @@ -350,7 +336,6 @@ public function setRequest(Request $request) * Set whether the subject should be "locked". * * @param bool $lock - * * @return $this */ public function lockSubject($lock) @@ -405,10 +390,9 @@ public function blacklist() * * @param string $method * @param array $parameters + * @return mixed * * @throws \BadMethodCallException - * - * @return mixed */ public function __call($method, $parameters) { diff --git a/src/JWTAuth.php b/src/JWTAuth.php index 38612bea4..e8ab72729 100644 --- a/src/JWTAuth.php +++ b/src/JWTAuth.php @@ -30,7 +30,6 @@ class JWTAuth extends JWT * @param \Tymon\JWTAuth\Manager $manager * @param \Tymon\JWTAuth\Contracts\Providers\Auth $auth * @param \Tymon\JWTAuth\Http\Parser\Parser $parser - * * @return void */ public function __construct(Manager $manager, Auth $auth, Parser $parser) @@ -43,7 +42,6 @@ public function __construct(Manager $manager, Auth $auth, Parser $parser) * Attempt to authenticate the user and return the token. * * @param array $credentials - * * @return false|string */ public function attempt(array $credentials) diff --git a/src/JWTGuard.php b/src/JWTGuard.php index 28f477fa6..31957072e 100644 --- a/src/JWTGuard.php +++ b/src/JWTGuard.php @@ -54,7 +54,6 @@ class JWTGuard implements Guard * @param \Tymon\JWTAuth\JWT $jwt * @param \Illuminate\Contracts\Auth\UserProvider $provider * @param \Illuminate\Http\Request $request - * * @return void */ public function __construct(JWT $jwt, UserProvider $provider, Request $request) @@ -86,9 +85,9 @@ public function user() /** * Get the currently authenticated user or throws an exception. * - * @throws \Tymon\JWTAuth\Exceptions\UserNotDefinedException - * * @return \Illuminate\Contracts\Auth\Authenticatable + * + * @throws \Tymon\JWTAuth\Exceptions\UserNotDefinedException */ public function userOrFail() { @@ -103,7 +102,6 @@ public function userOrFail() * Validate a user's credentials. * * @param array $credentials - * * @return bool */ public function validate(array $credentials = []) @@ -116,7 +114,6 @@ public function validate(array $credentials = []) * * @param array $credentials * @param bool $login - * * @return bool|string */ public function attempt(array $credentials = [], $login = true) @@ -134,7 +131,6 @@ public function attempt(array $credentials = [], $login = true) * Create a token for a user. * * @param \Tymon\JWTAuth\Contracts\JWTSubject $user - * * @return string */ public function login(JWTSubject $user) @@ -149,7 +145,6 @@ public function login(JWTSubject $user) * Logout the user, thus invalidating the token. * * @param bool $forceForever - * * @return void */ public function logout($forceForever = false) @@ -165,7 +160,6 @@ public function logout($forceForever = false) * * @param bool $forceForever * @param bool $resetClaims - * * @return string */ public function refresh($forceForever = false, $resetClaims = false) @@ -177,7 +171,6 @@ public function refresh($forceForever = false, $resetClaims = false) * Invalidate the token. * * @param bool $forceForever - * * @return \Tymon\JWTAuth\JWT */ public function invalidate($forceForever = false) @@ -189,7 +182,6 @@ public function invalidate($forceForever = false) * Create a new token by User id. * * @param mixed $id - * * @return string|null */ public function tokenById($id) @@ -203,7 +195,6 @@ public function tokenById($id) * Log a user into the application using their credentials. * * @param array $credentials - * * @return bool */ public function once(array $credentials = []) @@ -221,7 +212,6 @@ public function once(array $credentials = []) * Log the given User into the application. * * @param mixed $id - * * @return bool */ public function onceUsingId($id) @@ -239,7 +229,6 @@ public function onceUsingId($id) * Alias for onceUsingId. * * @param mixed $id - * * @return bool */ public function byId($id) @@ -251,7 +240,6 @@ public function byId($id) * Add any custom claims. * * @param array $claims - * * @return $this */ public function claims(array $claims) @@ -285,7 +273,6 @@ public function payload() * Set the token. * * @param \Tymon\JWTAuth\Token|string $token - * * @return $this */ public function setToken($token) @@ -299,7 +286,6 @@ public function setToken($token) * Set the token ttl. * * @param int $ttl - * * @return $this */ public function setTTL($ttl) @@ -323,7 +309,6 @@ public function getProvider() * Set the user provider used by the guard. * * @param \Illuminate\Contracts\Auth\UserProvider $provider - * * @return $this */ public function setProvider(UserProvider $provider) @@ -357,7 +342,6 @@ public function getRequest() * Set the current request instance. * * @param \Illuminate\Http\Request $request - * * @return $this */ public function setRequest(Request $request) @@ -382,7 +366,6 @@ public function getLastAttempted() * * @param mixed $user * @param array $credentials - * * @return bool */ protected function hasValidCredentials($user, $credentials) @@ -393,7 +376,7 @@ protected function hasValidCredentials($user, $credentials) /** * Ensure the JWTSubject matches what is in the token. * - * @return bool + * @return bool */ protected function validateSubject() { @@ -409,9 +392,9 @@ protected function validateSubject() /** * Ensure that a token is available in the request. * - * @throws \Tymon\JWTAuth\Exceptions\JWTException - * * @return \Tymon\JWTAuth\JWT + * + * @throws \Tymon\JWTAuth\Exceptions\JWTException */ protected function requireToken() { @@ -427,10 +410,9 @@ protected function requireToken() * * @param string $method * @param array $parameters + * @return mixed * * @throws \BadMethodCallException - * - * @return mixed */ public function __call($method, $parameters) { diff --git a/src/Manager.php b/src/Manager.php index 9ada53d08..a1e8edfb7 100644 --- a/src/Manager.php +++ b/src/Manager.php @@ -62,7 +62,6 @@ class Manager * @param \Tymon\JWTAuth\Contracts\Providers\JWT $provider * @param \Tymon\JWTAuth\Blacklist $blacklist * @param \Tymon\JWTAuth\Factory $payloadFactory - * * @return void */ public function __construct(JWTContract $provider, Blacklist $blacklist, Factory $payloadFactory) @@ -76,7 +75,6 @@ public function __construct(JWTContract $provider, Blacklist $blacklist, Factory * Encode a Payload and return the Token. * * @param \Tymon\JWTAuth\Payload $payload - * * @return \Tymon\JWTAuth\Token */ public function encode(Payload $payload) @@ -91,10 +89,9 @@ public function encode(Payload $payload) * * @param \Tymon\JWTAuth\Token $token * @param bool $checkBlacklist + * @return \Tymon\JWTAuth\Payload * * @throws \Tymon\JWTAuth\Exceptions\TokenBlacklistedException - * - * @return \Tymon\JWTAuth\Payload */ public function decode(Token $token, $checkBlacklist = true) { @@ -118,7 +115,6 @@ public function decode(Token $token, $checkBlacklist = true) * @param \Tymon\JWTAuth\Token $token * @param bool $forceForever * @param bool $resetClaims - * * @return \Tymon\JWTAuth\Token */ public function refresh(Token $token, $forceForever = false, $resetClaims = false) @@ -143,10 +139,9 @@ public function refresh(Token $token, $forceForever = false, $resetClaims = fals * * @param \Tymon\JWTAuth\Token $token * @param bool $forceForever + * @return bool * * @throws \Tymon\JWTAuth\Exceptions\JWTException - * - * @return bool */ public function invalidate(Token $token, $forceForever = false) { @@ -164,7 +159,6 @@ public function invalidate(Token $token, $forceForever = false) * Build the claims to go into the refreshed token. * * @param \Tymon\JWTAuth\Payload $payload - * * @return array */ protected function buildRefreshClaims(Payload $payload) @@ -219,7 +213,6 @@ public function getBlacklist() * Set whether the blacklist is enabled. * * @param bool $enabled - * * @return $this */ public function setBlacklistEnabled($enabled) @@ -233,7 +226,6 @@ public function setBlacklistEnabled($enabled) * Set the claims to be persisted when refreshing a token. * * @param array $claims - * * @return $this */ public function setPersistentClaims(array $claims) diff --git a/src/Payload.php b/src/Payload.php index b7b49974d..76f0f838f 100644 --- a/src/Payload.php +++ b/src/Payload.php @@ -39,7 +39,6 @@ class Payload implements ArrayAccess, Arrayable, Countable, Jsonable, JsonSerial * @param \Tymon\JWTAuth\Claims\Collection $claims * @param \Tymon\JWTAuth\Validators\PayloadValidator $validator * @param bool $refreshFlow - * * @return void */ public function __construct(Collection $claims, PayloadValidator $validator, $refreshFlow = false) @@ -62,7 +61,6 @@ public function getClaims() * * @param array $values * @param bool $strict - * * @return bool */ public function matches(array $values, $strict = false) @@ -86,7 +84,6 @@ public function matches(array $values, $strict = false) * Checks if a payload strictly matches some expected values. * * @param array $values - * * @return bool */ public function matchesStrict(array $values) @@ -98,7 +95,6 @@ public function matchesStrict(array $values) * Get the payload. * * @param mixed $claim - * * @return mixed */ public function get($claim = null) @@ -120,7 +116,6 @@ public function get($claim = null) * Get the underlying Claim instance. * * @param string $claim - * * @return \Tymon\JWTAuth\Claims\Claim */ public function getInternal($claim) @@ -132,7 +127,6 @@ public function getInternal($claim) * Determine whether the payload has the claim (by instance). * * @param \Tymon\JWTAuth\Claims\Claim $claim - * * @return bool */ public function has(Claim $claim) @@ -144,7 +138,6 @@ public function has(Claim $claim) * Determine whether the payload has the claim (by key). * * @param string $claim - * * @return bool */ public function hasKey($claim) @@ -176,7 +169,6 @@ public function jsonSerialize() * Get the payload as JSON. * * @param int $options - * * @return string */ public function toJson($options = JSON_UNESCAPED_SLASHES) @@ -198,7 +190,6 @@ public function __toString() * Determine if an item exists at an offset. * * @param mixed $key - * * @return bool */ public function offsetExists($key) @@ -210,7 +201,6 @@ public function offsetExists($key) * Get an item at a given offset. * * @param mixed $key - * * @return mixed */ public function offsetGet($key) @@ -235,10 +225,9 @@ public function offsetSet($key, $value) * Don't allow changing the payload as it should be immutable. * * @param string $key + * @return void * * @throws \Tymon\JWTAuth\Exceptions\PayloadException - * - * @return void */ public function offsetUnset($key) { @@ -259,7 +248,6 @@ public function count() * Invoke the Payload as a callable function. * * @param mixed $claim - * * @return mixed */ public function __invoke($claim = null) @@ -272,10 +260,9 @@ public function __invoke($claim = null) * * @param string $method * @param array $parameters + * @return mixed * * @throws \BadMethodCallException - * - * @return mixed */ public function __call($method, $parameters) { diff --git a/src/Providers/AbstractServiceProvider.php b/src/Providers/AbstractServiceProvider.php index 45d629969..2d782c0e2 100644 --- a/src/Providers/AbstractServiceProvider.php +++ b/src/Providers/AbstractServiceProvider.php @@ -346,7 +346,6 @@ protected function registerJWTCommand() * * @param string $key * @param string $default - * * @return mixed */ protected function config($key, $default = null) @@ -358,7 +357,6 @@ protected function config($key, $default = null) * Get an instantiable configuration instance. * * @param string $key - * * @return mixed */ protected function getConfigInstance($key) diff --git a/src/Providers/Auth/Illuminate.php b/src/Providers/Auth/Illuminate.php index 486c36501..c010e93e5 100644 --- a/src/Providers/Auth/Illuminate.php +++ b/src/Providers/Auth/Illuminate.php @@ -27,7 +27,6 @@ class Illuminate implements Auth * Constructor. * * @param \Illuminate\Contracts\Auth\Guard $auth - * * @return void */ public function __construct(GuardContract $auth) @@ -39,7 +38,6 @@ public function __construct(GuardContract $auth) * Check a user's credentials. * * @param array $credentials - * * @return bool */ public function byCredentials(array $credentials) @@ -51,7 +49,6 @@ public function byCredentials(array $credentials) * Authenticate a user via the id. * * @param mixed $id - * * @return bool */ public function byId($id) diff --git a/src/Providers/JWT/Lcobucci.php b/src/Providers/JWT/Lcobucci.php index 6b1e40ff0..a4e9a66d6 100644 --- a/src/Providers/JWT/Lcobucci.php +++ b/src/Providers/JWT/Lcobucci.php @@ -11,31 +11,31 @@ namespace Tymon\JWTAuth\Providers\JWT; -use Exception; use DateTimeImmutable; use DateTimeInterface; +use Exception; +use Illuminate\Support\Collection; +use Lcobucci\JWT\Configuration; use Lcobucci\JWT\Signer; -use Lcobucci\JWT\Signer\Rsa; use Lcobucci\JWT\Signer\Ecdsa; -use Lcobucci\JWT\Configuration; -use Lcobucci\JWT\Token\Builder; -use Illuminate\Support\Collection; use Lcobucci\JWT\Signer\Key\InMemory; +use Lcobucci\JWT\Signer\Rsa; +use Lcobucci\JWT\Token\Builder; use Lcobucci\JWT\Token\RegisteredClaims; +use Lcobucci\JWT\Validation\Constraint\SignedWith; use Tymon\JWTAuth\Contracts\Providers\JWT; use Tymon\JWTAuth\Exceptions\JWTException; -use Lcobucci\JWT\Validation\Constraint\SignedWith; use Tymon\JWTAuth\Exceptions\TokenInvalidException; class Lcobucci extends Provider implements JWT { /** - * \Lcobucci\JWT\Signer + * \Lcobucci\JWT\Signer. */ protected $signer; /** - * \Lcobucci\JWT\Configuration + * \Lcobucci\JWT\Configuration. */ protected $config; @@ -46,7 +46,6 @@ class Lcobucci extends Provider implements JWT * @param string $algo * @param array $keys * @param \Lcobucci\JWT\Configuration|null $config - * * @return void */ public function __construct($secret, $algo, array $keys, $config = null) @@ -78,10 +77,9 @@ public function __construct($secret, $algo, array $keys, $config = null) * Create a JSON Web Token. * * @param array $payload + * @return string * * @throws \Tymon\JWTAuth\Exceptions\JWTException - * - * @return string */ public function encode(array $payload) { @@ -100,10 +98,9 @@ public function encode(array $payload) * Decode a JSON Web Token. * * @param string $token + * @return array * * @throws \Tymon\JWTAuth\Exceptions\JWTException - * - * @return array */ public function decode($token) { @@ -135,7 +132,6 @@ public function decode($token) * Create an instance of the builder with all of the claims applied. * * @param array $payload - * * @return \Lcobucci\JWT\Token\Builder */ protected function getBuilderFromClaims(array $payload): Builder @@ -198,9 +194,9 @@ protected function buildConfig(): Configuration /** * Get the signer instance. * - * @throws \Tymon\JWTAuth\Exceptions\JWTException - * * @return \Lcobucci\JWT\Signer + * + * @throws \Tymon\JWTAuth\Exceptions\JWTException */ protected function getSigner() { diff --git a/src/Providers/JWT/Namshi.php b/src/Providers/JWT/Namshi.php index 79e78f65f..2e72398f4 100644 --- a/src/Providers/JWT/Namshi.php +++ b/src/Providers/JWT/Namshi.php @@ -37,7 +37,6 @@ class Namshi extends Provider implements JWT * @param string $secret * @param string $algo * @param array $keys - * * @return void */ public function __construct(JWS $jws, $secret, $algo, array $keys) @@ -51,10 +50,9 @@ public function __construct(JWS $jws, $secret, $algo, array $keys) * Create a JSON Web Token. * * @param array $payload + * @return string * * @throws \Tymon\JWTAuth\Exceptions\JWTException - * - * @return string */ public function encode(array $payload) { @@ -71,10 +69,9 @@ public function encode(array $payload) * Decode a JSON Web Token. * * @param string $token + * @return array * * @throws \Tymon\JWTAuth\Exceptions\JWTException - * - * @return array */ public function decode($token) { diff --git a/src/Providers/JWT/Provider.php b/src/Providers/JWT/Provider.php index 2933e6b0d..7e614da48 100644 --- a/src/Providers/JWT/Provider.php +++ b/src/Providers/JWT/Provider.php @@ -52,7 +52,6 @@ abstract class Provider * @param string $secret * @param string $algo * @param array $keys - * * @return void */ public function __construct($secret, $algo, array $keys) @@ -66,7 +65,6 @@ public function __construct($secret, $algo, array $keys) * Set the algorithm used to sign the token. * * @param string $algo - * * @return $this */ public function setAlgo($algo) @@ -90,7 +88,6 @@ public function getAlgo() * Set the secret used to sign the token. * * @param string $secret - * * @return $this */ public function setSecret($secret) @@ -114,7 +111,6 @@ public function getSecret() * Set the keys used to sign the token. * * @param array $keys - * * @return $this */ public function setKeys(array $keys) diff --git a/src/Providers/Storage/Illuminate.php b/src/Providers/Storage/Illuminate.php index 70f9159c9..b12496855 100644 --- a/src/Providers/Storage/Illuminate.php +++ b/src/Providers/Storage/Illuminate.php @@ -46,7 +46,6 @@ class Illuminate implements Storage * Constructor. * * @param \Illuminate\Contracts\Cache\Repository $cache - * * @return void */ public function __construct(CacheContract $cache) @@ -60,7 +59,6 @@ public function __construct(CacheContract $cache) * @param string $key * @param mixed $value * @param int $minutes - * * @return void */ public function add($key, $value, $minutes) @@ -81,7 +79,6 @@ public function add($key, $value, $minutes) * * @param string $key * @param mixed $value - * * @return void */ public function forever($key, $value) @@ -93,7 +90,6 @@ public function forever($key, $value) * Get an item from storage. * * @param string $key - * * @return mixed */ public function get($key) @@ -105,7 +101,6 @@ public function get($key) * Remove an item from storage. * * @param string $key - * * @return bool */ public function destroy($key) diff --git a/src/Support/CustomClaims.php b/src/Support/CustomClaims.php index d5443eb99..e1d06b250 100644 --- a/src/Support/CustomClaims.php +++ b/src/Support/CustomClaims.php @@ -24,7 +24,6 @@ trait CustomClaims * Set the custom claims. * * @param array $customClaims - * * @return $this */ public function customClaims(array $customClaims) @@ -38,7 +37,6 @@ public function customClaims(array $customClaims) * Alias to set the custom claims. * * @param array $customClaims - * * @return $this */ public function claims(array $customClaims) diff --git a/src/Support/RefreshFlow.php b/src/Support/RefreshFlow.php index 988b6eae1..9807c1c97 100644 --- a/src/Support/RefreshFlow.php +++ b/src/Support/RefreshFlow.php @@ -24,7 +24,6 @@ trait RefreshFlow * Set the refresh flow flag. * * @param bool $refreshFlow - * * @return $this */ public function setRefreshFlow($refreshFlow = true) diff --git a/src/Support/Utils.php b/src/Support/Utils.php index 5738e6ed7..2b341c798 100644 --- a/src/Support/Utils.php +++ b/src/Support/Utils.php @@ -29,7 +29,6 @@ public static function now() * Get the Carbon instance for the timestamp. * * @param int $timestamp - * * @return \Carbon\Carbon */ public static function timestamp($timestamp) @@ -42,7 +41,6 @@ public static function timestamp($timestamp) * * @param int $timestamp * @param int $leeway - * * @return bool */ public static function isPast($timestamp, $leeway = 0) @@ -59,7 +57,6 @@ public static function isPast($timestamp, $leeway = 0) * * @param int $timestamp * @param int $leeway - * * @return bool */ public static function isFuture($timestamp, $leeway = 0) diff --git a/src/Token.php b/src/Token.php index a51a73626..3b9d6add1 100644 --- a/src/Token.php +++ b/src/Token.php @@ -24,7 +24,6 @@ class Token * Create a new JSON Web Token. * * @param string $value - * * @return void */ public function __construct($value) diff --git a/src/Validators/PayloadValidator.php b/src/Validators/PayloadValidator.php index d8e6de220..f10ff1302 100644 --- a/src/Validators/PayloadValidator.php +++ b/src/Validators/PayloadValidator.php @@ -41,7 +41,6 @@ class PayloadValidator extends Validator * Run the validations on the payload array. * * @param \Tymon\JWTAuth\Claims\Collection $value - * * @return \Tymon\JWTAuth\Claims\Collection */ public function check($value) @@ -56,10 +55,9 @@ public function check($value) * the claims have the relevant type. * * @param \Tymon\JWTAuth\Claims\Collection $claims + * @return void * * @throws \Tymon\JWTAuth\Exceptions\TokenInvalidException - * - * @return void */ protected function validateStructure(Collection $claims) { @@ -72,11 +70,10 @@ protected function validateStructure(Collection $claims) * Validate the payload timestamps. * * @param \Tymon\JWTAuth\Claims\Collection $claims + * @return \Tymon\JWTAuth\Claims\Collection * * @throws \Tymon\JWTAuth\Exceptions\TokenExpiredException * @throws \Tymon\JWTAuth\Exceptions\TokenInvalidException - * - * @return \Tymon\JWTAuth\Claims\Collection */ protected function validatePayload(Collection $claims) { @@ -87,10 +84,9 @@ protected function validatePayload(Collection $claims) * Check the token in the refresh flow context. * * @param \Tymon\JWTAuth\Claims\Collection $claims + * @return \Tymon\JWTAuth\Claims\Collection * * @throws \Tymon\JWTAuth\Exceptions\TokenExpiredException - * - * @return \Tymon\JWTAuth\Claims\Collection */ protected function validateRefresh(Collection $claims) { @@ -101,7 +97,6 @@ protected function validateRefresh(Collection $claims) * Set the required claims. * * @param array $claims - * * @return $this */ public function setRequiredClaims(array $claims) @@ -115,7 +110,6 @@ public function setRequiredClaims(array $claims) * Set the refresh ttl. * * @param int $ttl - * * @return $this */ public function setRefreshTTL($ttl) diff --git a/src/Validators/TokenValidator.php b/src/Validators/TokenValidator.php index b76f13e9e..6beb051ec 100644 --- a/src/Validators/TokenValidator.php +++ b/src/Validators/TokenValidator.php @@ -19,7 +19,6 @@ class TokenValidator extends Validator * Check the structure of the token. * * @param string $value - * * @return string */ public function check($value) @@ -29,10 +28,9 @@ public function check($value) /** * @param string $token + * @return string * * @throws \Tymon\JWTAuth\Exceptions\TokenInvalidException - * - * @return string */ protected function validateStructure($token) { diff --git a/src/Validators/Validator.php b/src/Validators/Validator.php index 6f05a462c..18d9a683d 100644 --- a/src/Validators/Validator.php +++ b/src/Validators/Validator.php @@ -23,7 +23,6 @@ abstract class Validator implements ValidatorContract * Helper function to return a boolean. * * @param array $value - * * @return bool */ public function isValid($value) @@ -41,7 +40,6 @@ public function isValid($value) * Run the validation. * * @param array $value - * * @return void */ abstract public function check($value); diff --git a/tests/BlacklistTest.php b/tests/BlacklistTest.php index 7412e82d3..df3e76cf8 100644 --- a/tests/BlacklistTest.php +++ b/tests/BlacklistTest.php @@ -202,7 +202,7 @@ public function blacklist_provider() * @test * @dataProvider blacklist_provider * - * @param mixed $result + * @param mixed $result */ public function it_should_check_whether_a_token_has_not_been_blacklisted($result) { diff --git a/tests/PayloadTest.php b/tests/PayloadTest.php index 5d6263de6..ca1e0c17c 100644 --- a/tests/PayloadTest.php +++ b/tests/PayloadTest.php @@ -47,7 +47,6 @@ public function setUp(): void /** * @param array $extraClaims - * * @return \Tymon\JWTAuth\Payload */ private function getTestPayload(array $extraClaims = []) diff --git a/tests/Providers/JWT/LcobucciTest.php b/tests/Providers/JWT/LcobucciTest.php index 057cda8bd..acce316d1 100644 --- a/tests/Providers/JWT/LcobucciTest.php +++ b/tests/Providers/JWT/LcobucciTest.php @@ -11,11 +11,11 @@ namespace Tymon\JWTAuth\Test\Providers\JWT; -use Tymon\JWTAuth\Test\AbstractTestCase; -use Tymon\JWTAuth\Providers\JWT\Lcobucci; -use Tymon\JWTAuth\Providers\JWT\Provider; use Tymon\JWTAuth\Exceptions\JWTException; use Tymon\JWTAuth\Exceptions\TokenInvalidException; +use Tymon\JWTAuth\Providers\JWT\Lcobucci; +use Tymon\JWTAuth\Providers\JWT\Provider; +use Tymon\JWTAuth\Test\AbstractTestCase; class LcobucciTest extends AbstractTestCase { From a8a33fb0e54cd3df5ac9c88b54b366d96e297764 Mon Sep 17 00:00:00 2001 From: Sean Tymon Date: Thu, 7 Apr 2022 09:20:59 +0000 Subject: [PATCH 05/10] chore: Remove support for php <7.4 --- .github/workflows/phpunit.yml | 8 +------- composer.json | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 2f31b4b70..30c843d49 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -14,7 +14,7 @@ jobs: strategy: fail-fast: false matrix: - php: [7.2, 7.3, 7.4, 8.0, 8.1] + php: [7.4, 8.0, 8.1] laravel: [6.*, 7.*, 8.*, 9.*] os: [ubuntu-latest] coverage: [none] @@ -24,12 +24,6 @@ jobs: os: ubuntu-latest coverage: xdebug exclude: - - php: 7.2 - laravel: 8.* - - php: 7.2 - laravel: 9.* - - php: 7.3 - laravel: 9.* - php: 7.4 laravel: 9.* diff --git a/composer.json b/composer.json index e1e43cc14..077e69627 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ } ], "require": { - "php": "^7.2|^8.0", + "php": "^7.4|^8.0", "illuminate/auth": "^5.2|^6|^7|^8|^9", "illuminate/contracts": "^5.2|^6|^7|^8|^9", "illuminate/http": "^5.2|^6|^7|^8|^9", From bc4ec80096d0331fa2236f42f9b4c0aa2ad3ae88 Mon Sep 17 00:00:00 2001 From: Sean Tymon Date: Thu, 7 Apr 2022 10:24:13 +0100 Subject: [PATCH 06/10] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f0b1b6f39..6d6d2edb9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![jwt-auth-banner](https://cloud.githubusercontent.com/assets/1801923/9915273/119b9350-5cae-11e5-850b-c941cac60b32.png) -[![PHPUnit](https://github.com/tymondesigns/jwt-auth/workflows/PHPUnit%20tests/badge.svg)](https://travis-ci.org/tymondesigns/jwt-auth) +[![PHPUnit](https://github.com/tymondesigns/jwt-auth/workflows/PHPUnit%20tests/badge.svg)](https://github.com/tymondesigns/jwt-auth/actions) [![Codecov branch](https://img.shields.io/codecov/c/github/tymondesigns/jwt-auth/develop.svg?style=flat-square&logo=codecov)](https://codecov.io/github/tymondesigns/jwt-auth) [![StyleCI](https://styleci.io/repos/23680678/shield?style=flat-square)](https://styleci.io/repos/23680678) [![Latest Version](http://img.shields.io/packagist/v/tymon/jwt-auth.svg?style=flat-square&logo=composer)](https://packagist.org/packages/tymon/jwt-auth) From 0f5ea5db337909f5c4618fc4ec8e7ec6e51b5661 Mon Sep 17 00:00:00 2001 From: Sean Tymon Date: Tue, 12 Apr 2022 10:12:19 +0000 Subject: [PATCH 07/10] chore: Suppress deprecation notices --- src/Claims/Claim.php | 1 + src/Payload.php | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/Claims/Claim.php b/src/Claims/Claim.php index c44ebcf8a..5dcd123ef 100644 --- a/src/Claims/Claim.php +++ b/src/Claims/Claim.php @@ -138,6 +138,7 @@ public function matches($value, $strict = true) * * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->toArray(); diff --git a/src/Payload.php b/src/Payload.php index 76f0f838f..13b2a78f6 100644 --- a/src/Payload.php +++ b/src/Payload.php @@ -160,6 +160,7 @@ public function toArray() * * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->toArray(); @@ -192,6 +193,7 @@ public function __toString() * @param mixed $key * @return bool */ + #[\ReturnTypeWillChange] public function offsetExists($key) { return Arr::has($this->toArray(), $key); @@ -216,6 +218,7 @@ public function offsetGet($key) * * @throws \Tymon\JWTAuth\Exceptions\PayloadException */ + #[\ReturnTypeWillChange] public function offsetSet($key, $value) { throw new PayloadException('The payload is immutable'); @@ -229,6 +232,7 @@ public function offsetSet($key, $value) * * @throws \Tymon\JWTAuth\Exceptions\PayloadException */ + #[\ReturnTypeWillChange] public function offsetUnset($key) { throw new PayloadException('The payload is immutable'); @@ -239,6 +243,7 @@ public function offsetUnset($key) * * @return int */ + #[\ReturnTypeWillChange] public function count() { return count($this->toArray()); From 185d9ad68fa3ab582773f74ee4f6fe683f3512c7 Mon Sep 17 00:00:00 2001 From: Sean Tymon Date: Fri, 22 Apr 2022 08:21:42 +0000 Subject: [PATCH 08/10] fix: Throw exception when required keys are not set. --- src/Payload.php | 1 + src/Providers/JWT/Lcobucci.php | 57 ++++++++++++++++++++++------ src/Providers/JWT/Provider.php | 8 ++-- tests/Providers/JWT/LcobucciTest.php | 52 +++++++++++++++++++++++-- 4 files changed, 98 insertions(+), 20 deletions(-) diff --git a/src/Payload.php b/src/Payload.php index 13b2a78f6..f60129b8a 100644 --- a/src/Payload.php +++ b/src/Payload.php @@ -205,6 +205,7 @@ public function offsetExists($key) * @param mixed $key * @return mixed */ + #[\ReturnTypeWillChange] public function offsetGet($key) { return Arr::get($this->toArray(), $key); diff --git a/src/Providers/JWT/Lcobucci.php b/src/Providers/JWT/Lcobucci.php index a4e9a66d6..ab4c38860 100644 --- a/src/Providers/JWT/Lcobucci.php +++ b/src/Providers/JWT/Lcobucci.php @@ -11,20 +11,21 @@ namespace Tymon\JWTAuth\Providers\JWT; +use Exception; use DateTimeImmutable; use DateTimeInterface; -use Exception; -use Illuminate\Support\Collection; -use Lcobucci\JWT\Configuration; use Lcobucci\JWT\Signer; -use Lcobucci\JWT\Signer\Ecdsa; -use Lcobucci\JWT\Signer\Key\InMemory; +use Lcobucci\JWT\Signer\Key; use Lcobucci\JWT\Signer\Rsa; +use Lcobucci\JWT\Signer\Ecdsa; +use Lcobucci\JWT\Configuration; use Lcobucci\JWT\Token\Builder; +use Illuminate\Support\Collection; +use Lcobucci\JWT\Signer\Key\InMemory; use Lcobucci\JWT\Token\RegisteredClaims; -use Lcobucci\JWT\Validation\Constraint\SignedWith; use Tymon\JWTAuth\Contracts\Providers\JWT; use Tymon\JWTAuth\Exceptions\JWTException; +use Lcobucci\JWT\Validation\Constraint\SignedWith; use Tymon\JWTAuth\Exceptions\TokenInvalidException; class Lcobucci extends Provider implements JWT @@ -226,23 +227,55 @@ protected function isAsymmetric() * {@inheritdoc} * * @return \Lcobucci\JWT\Signer\Key + * + * @throws \Tymon\JWTAuth\Exceptions\JWTException */ protected function getSigningKey() { - return $this->isAsymmetric() - ? InMemory::plainText($this->getPrivateKey(), $this->getPassphrase() ?? '') - : InMemory::plainText($this->getSecret()); + if ($this->isAsymmetric()) { + if (! $privateKey = $this->getPrivateKey()) { + throw new JWTException('Private key is not set.'); + } + + return $this->getKey($privateKey, $this->getPassphrase() ?? ''); + } + + if (! $secret = $this->getSecret()) { + throw new JWTException('Secret is not set.'); + } + + return $this->getKey($secret); } /** * {@inheritdoc} * * @return \Lcobucci\JWT\Signer\Key + * + * @throws \Tymon\JWTAuth\Exceptions\JWTException */ protected function getVerificationKey() { - return $this->isAsymmetric() - ? InMemory::plainText($this->getPublicKey()) - : InMemory::plainText($this->getSecret()); + if ($this->isAsymmetric()) { + if (! $public = $this->getPublicKey()) { + throw new JWTException('Public key is not set.'); + } + + return $this->getKey($public); + } + + if (! $secret = $this->getSecret()) { + throw new JWTException('Secret is not set.'); + } + + return $this->getKey($secret); + } + + /** + * Get the signing key instance. + */ + protected function getKey(string $contents, string $passphrase = ''): Key + { + return InMemory::plainText($contents, $passphrase); } } diff --git a/src/Providers/JWT/Provider.php b/src/Providers/JWT/Provider.php index 7e614da48..2ec62bddb 100644 --- a/src/Providers/JWT/Provider.php +++ b/src/Providers/JWT/Provider.php @@ -133,7 +133,7 @@ public function getKeys() /** * Get the public key used to sign tokens with an asymmetric algorithm. * - * @return resource|string|null + * @return string|null */ public function getPublicKey() { @@ -143,7 +143,7 @@ public function getPublicKey() /** * Get the private key used to sign tokens with an asymmetric algorithm. * - * @return resource|string|null + * @return string|null */ public function getPrivateKey() { @@ -164,7 +164,7 @@ public function getPassphrase() /** * Get the key used to sign the tokens. * - * @return resource|string|null + * @return string|null */ protected function getSigningKey() { @@ -174,7 +174,7 @@ protected function getSigningKey() /** * Get the key used to verify the tokens. * - * @return resource|string|null + * @return string|null */ protected function getVerificationKey() { diff --git a/tests/Providers/JWT/LcobucciTest.php b/tests/Providers/JWT/LcobucciTest.php index acce316d1..a6a61c58b 100644 --- a/tests/Providers/JWT/LcobucciTest.php +++ b/tests/Providers/JWT/LcobucciTest.php @@ -146,11 +146,11 @@ public function it_should_throw_a_token_invalid_exception_when_the_token_could_n $this->expectException(TokenInvalidException::class); $this->expectExceptionMessage('Could not decode token:'); - $this->getProvider('secret', 'HS256')->decode('foo.bar.baz'); + $this->getProvider('secret', Provider::ALGO_HS256)->decode('foo.bar.baz'); } /** @test */ - public function it_should_throw_a_exception_when_the_algorithm_passed_is_invalid() + public function it_should_throw_an_exception_when_the_algorithm_passed_is_invalid() { $this->expectException(JWTException::class); $this->expectExceptionMessage('The given algorithm could not be found'); @@ -158,12 +158,56 @@ public function it_should_throw_a_exception_when_the_algorithm_passed_is_invalid $this->getProvider('secret', 'INVALID_ALGO')->decode('foo.bar.baz'); } + /** @test */ + public function it_should_throw_an_exception_when_no_symmetric_key_is_provided_when_encoding() + { + $this->expectException(JWTException::class); + $this->expectExceptionMessage('Secret is not set.'); + + $this->getProvider(null, Provider::ALGO_HS256)->encode(['sub' => 1]); + } + + /** @test */ + public function it_should_throw_an_exception_when_no_symmetric_key_is_provided_when_decoding() + { + $this->expectException(JWTException::class); + $this->expectExceptionMessage('Secret is not set.'); + + $this->getProvider(null, Provider::ALGO_HS256)->decode('foo.bar.baz'); + } + + /** @test */ + public function it_should_throw_an_exception_when_no_asymmetric_public_key_is_provided() + { + $this->expectException(JWTException::class); + $this->expectExceptionMessage('Public key is not set.'); + + $this->getProvider( + 'does_not_matter', + Provider::ALGO_RS256, + ['private' => $this->getDummyPrivateKey(), 'public' => null] + )->decode('foo.bar.baz'); + } + + /** @test */ + public function it_should_throw_an_exception_when_no_asymmetric_private_key_is_provided() + { + $this->expectException(JWTException::class); + $this->expectExceptionMessage('Private key is not set.'); + + $this->getProvider( + 'does_not_matter', + Provider::ALGO_RS256, + ['private' => null, 'public' => $this->getDummyPublicKey()] + )->encode(['sub' => 1]); + } + /** @test */ public function it_should_return_the_public_key() { $provider = $this->getProvider( 'does_not_matter', - 'RS256', + Provider::ALGO_RS256, $keys = ['private' => $this->getDummyPrivateKey(), 'public' => $this->getDummyPublicKey()] ); @@ -175,7 +219,7 @@ public function it_should_return_the_keys() { $provider = $this->getProvider( 'does_not_matter', - 'RS256', + Provider::ALGO_RS256, $keys = ['private' => $this->getDummyPrivateKey(), 'public' => $this->getDummyPublicKey()] ); From feafb135e1ac4e64deb2100e28d3261033a2190f Mon Sep 17 00:00:00 2001 From: Sean Tymon Date: Fri, 22 Apr 2022 09:22:05 +0100 Subject: [PATCH 09/10] Apply fixes from StyleCI (#2180) [ci skip] [skip ci] --- src/Providers/JWT/Lcobucci.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Providers/JWT/Lcobucci.php b/src/Providers/JWT/Lcobucci.php index ab4c38860..4e08e561f 100644 --- a/src/Providers/JWT/Lcobucci.php +++ b/src/Providers/JWT/Lcobucci.php @@ -11,21 +11,21 @@ namespace Tymon\JWTAuth\Providers\JWT; -use Exception; use DateTimeImmutable; use DateTimeInterface; +use Exception; +use Illuminate\Support\Collection; +use Lcobucci\JWT\Configuration; use Lcobucci\JWT\Signer; +use Lcobucci\JWT\Signer\Ecdsa; use Lcobucci\JWT\Signer\Key; +use Lcobucci\JWT\Signer\Key\InMemory; use Lcobucci\JWT\Signer\Rsa; -use Lcobucci\JWT\Signer\Ecdsa; -use Lcobucci\JWT\Configuration; use Lcobucci\JWT\Token\Builder; -use Illuminate\Support\Collection; -use Lcobucci\JWT\Signer\Key\InMemory; use Lcobucci\JWT\Token\RegisteredClaims; +use Lcobucci\JWT\Validation\Constraint\SignedWith; use Tymon\JWTAuth\Contracts\Providers\JWT; use Tymon\JWTAuth\Exceptions\JWTException; -use Lcobucci\JWT\Validation\Constraint\SignedWith; use Tymon\JWTAuth\Exceptions\TokenInvalidException; class Lcobucci extends Provider implements JWT From 5285281370e356a81fba1a968bb7f50fc999fddd Mon Sep 17 00:00:00 2001 From: Sean Tymon Date: Wed, 27 Apr 2022 08:53:43 +0000 Subject: [PATCH 10/10] fix: Auth header not ignoring other auth schemes --- src/Http/Parser/AuthHeaders.php | 14 +++++++++++--- tests/Http/ParserTest.php | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/Http/Parser/AuthHeaders.php b/src/Http/Parser/AuthHeaders.php index da454e2e4..e3b68b4fe 100644 --- a/src/Http/Parser/AuthHeaders.php +++ b/src/Http/Parser/AuthHeaders.php @@ -51,11 +51,19 @@ public function parse(Request $request) { $header = $request->headers->get($this->header) ?: $this->fromAltHeaders($request); - if ($header) { - $start = strlen($this->prefix); + if ($header !== null) { + $position = strripos($header, $this->prefix); - return trim(substr($header, $start)); + if ($position !== false) { + $header = substr($header, $position + strlen($this->prefix)); + + return trim( + strpos($header, ',') !== false ? strstr($header, ',', true) : $header + ); + } } + + return null; } /** diff --git a/tests/Http/ParserTest.php b/tests/Http/ParserTest.php index feea3ccb9..f54f8a1db 100644 --- a/tests/Http/ParserTest.php +++ b/tests/Http/ParserTest.php @@ -108,6 +108,25 @@ public function it_should_return_the_token_from_the_alt_authorization_headers() $this->assertTrue($parser->hasToken()); } + /** @test */ + public function it_should_ignore_non_bearer_tokens() + { + $request = Request::create('foo', 'POST'); + $request->headers->set('Authorization', 'Basic OnBhc3N3b3Jk'); + + $parser = new Parser($request); + + $parser->setChain([ + new QueryString, + new InputSource, + new AuthHeaders, + new RouteParams, + ]); + + $this->assertNull($parser->parseToken()); + $this->assertFalse($parser->hasToken()); + } + /** @test */ public function it_should_not_strip_trailing_hyphens_from_the_authorization_header() {