├── .phpunit-watcher.yml ├── .styleci.yml ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── composer.json ├── config ├── di.php └── params.php ├── infection.json.dist ├── psalm.xml ├── rector.php └── src ├── JwtMethod.php ├── KeyFactory ├── FromCertificateFile.php ├── FromKeyFile.php ├── FromPKCS12CertificateFile.php └── FromSecret.php ├── KeyFactoryInterface.php ├── TokenFactory.php ├── TokenFactoryInterface.php ├── TokenRepository.php └── TokenRepositoryInterface.php /.phpunit-watcher.yml: -------------------------------------------------------------------------------- 1 | watch: 2 | directories: 3 | - src 4 | - tests 5 | fileMask: '*.php' 6 | notifications: 7 | passingTests: false 8 | failingTests: false 9 | phpunit: 10 | binaryPath: vendor/bin/phpunit 11 | timeout: 180 12 | -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | preset: psr12 2 | risky: true 3 | 4 | version: 8.1 5 | 6 | finder: 7 | exclude: 8 | - docs 9 | - vendor 10 | 11 | enabled: 12 | - alpha_ordered_traits 13 | - array_indentation 14 | - array_push 15 | - combine_consecutive_issets 16 | - combine_consecutive_unsets 17 | - combine_nested_dirname 18 | - declare_strict_types 19 | - dir_constant 20 | - fully_qualified_strict_types 21 | - function_to_constant 22 | - hash_to_slash_comment 23 | - is_null 24 | - logical_operators 25 | - magic_constant_casing 26 | - magic_method_casing 27 | - method_separation 28 | - modernize_types_casting 29 | - native_function_casing 30 | - native_function_type_declaration_casing 31 | - no_alias_functions 32 | - no_empty_comment 33 | - no_empty_phpdoc 34 | - no_empty_statement 35 | - no_extra_block_blank_lines 36 | - no_short_bool_cast 37 | - no_superfluous_elseif 38 | - no_unneeded_control_parentheses 39 | - no_unneeded_curly_braces 40 | - no_unneeded_final_method 41 | - no_unset_cast 42 | - no_unused_imports 43 | - no_unused_lambda_imports 44 | - no_useless_else 45 | - no_useless_return 46 | - normalize_index_brace 47 | - php_unit_dedicate_assert 48 | - php_unit_dedicate_assert_internal_type 49 | - php_unit_expectation 50 | - php_unit_mock 51 | - php_unit_mock_short_will_return 52 | - php_unit_namespaced 53 | - php_unit_no_expectation_annotation 54 | - phpdoc_no_empty_return 55 | - phpdoc_no_useless_inheritdoc 56 | - phpdoc_order 57 | - phpdoc_property 58 | - phpdoc_scalar 59 | - phpdoc_singular_inheritdoc 60 | - phpdoc_trim 61 | - phpdoc_trim_consecutive_blank_line_separation 62 | - phpdoc_type_to_var 63 | - phpdoc_types 64 | - phpdoc_types_order 65 | - print_to_echo 66 | - regular_callable_call 67 | - return_assignment 68 | - self_accessor 69 | - self_static_accessor 70 | - set_type_to_cast 71 | - short_array_syntax 72 | - short_list_syntax 73 | - simplified_if_return 74 | - single_quote 75 | - standardize_not_equals 76 | - ternary_to_null_coalescing 77 | - trailing_comma_in_multiline_array 78 | - unalign_double_arrow 79 | - unalign_equals 80 | - empty_loop_body_braces 81 | - integer_literal_case 82 | - union_type_without_spaces 83 | 84 | disabled: 85 | - function_declaration 86 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Yii Auth JWT Change Log 2 | 3 | ## 2.1.1 under development 4 | 5 | - no changes in this release. 6 | 7 | ## 2.1.0 August 20, 2024 8 | 9 | - Chg #82: Replace `web-token/*` with `web-token/jwt-library` and update min version of PHP to 8.1 (@rustamwin) 10 | - Enh #75: Add support for `psr/http-message` version `^2.0` (@vjik) 11 | 12 | ## 2.0.1 September 19, 2023 13 | 14 | - Bug #53: Add missed dependencies `psr/http-message`, `yiisoft/http` and `web-token/jwt-core` (@vjik) 15 | 16 | ## 2.0.0 February 13, 2023 17 | 18 | - Chg #59: Adapt configuration group names to Yii conventions (@vjik) 19 | 20 | ## 1.0.3 July 27, 2021 21 | 22 | - Fix #43: Added exception handling in `TokenRepository::getClaims()` with invalid token string (@strorch) 23 | 24 | ## 1.0.2 April 13, 2021 25 | 26 | - Chg: Adjust config for `yiisoft/factory` changes (@samdark) 27 | 28 | ## 1.0.1 March 23, 2021 29 | 30 | - Chg: Adjust config for new config plugin (@samdark) 31 | 32 | ## 1.0.0 February 11, 2021 33 | 34 | - Initial release. 35 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright © 2008 by Yii Software () 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions 6 | are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Yii Software nor the names of its 15 | contributors may be used to endorse or promote products derived 16 | from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 28 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Yii 4 | 5 |

Yii Auth JWT

6 |
7 |

8 | 9 | [![Latest Stable Version](https://poser.pugx.org/yiisoft/auth-jwt/v)](https://packagist.org/packages/yiisoft/auth-jwt) 10 | [![Total Downloads](https://poser.pugx.org/yiisoft/auth-jwt/downloads)](https://packagist.org/packages/yiisoft/auth-jwt) 11 | [![Build status](https://github.com/yiisoft/auth-jwt/actions/workflows/build.yml/badge.svg)](https://github.com/yiisoft/auth-jwt/actions/workflows/build.yml) 12 | [![Code Coverage](https://codecov.io/gh/yiisoft/auth-jwt/branch/master/graph/badge.svg)](https://codecov.io/gh/yiisoft/auth-jwt) 13 | [![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fyiisoft%2Fauth-jwt%2Fmaster)](https://dashboard.stryker-mutator.io/reports/github.com/yiisoft/auth-jwt/master) 14 | [![static analysis](https://github.com/yiisoft/auth-jwt/workflows/static%20analysis/badge.svg)](https://github.com/yiisoft/auth-jwt/actions?query=workflow%3A%22static+analysis%22) 15 | [![type-coverage](https://shepherd.dev/github/yiisoft/auth-jwt/coverage.svg)](https://shepherd.dev/github/yiisoft/auth-jwt) 16 | [![psalm-level](https://shepherd.dev/github/yiisoft/auth-jwt/level.svg)](https://shepherd.dev/github/yiisoft/auth-jwt) 17 | 18 | The package provides [JWT authentication](https://tools.ietf.org/html/rfc7519) method for [Yii Auth](https://github.com/yiisoft/auth/). 19 | 20 | ## Requirements 21 | 22 | - PHP 8.1 or higher. 23 | 24 | ## Installation 25 | 26 | The package could be installed with [Composer](https://getcomposer.org): 27 | 28 | ```shell 29 | composer require yiisoft/auth-jwt 30 | ``` 31 | 32 | ## General usage 33 | 34 | ### Configuring within Yii 35 | 36 | 1. Set JWT parameters in your `params.php` config file: 37 | 38 | ```php 39 | 'yiisoft/auth-jwt' => [ 40 | 'algorithms' => [ 41 | // your signature algorithms 42 | ], 43 | 'serializers' => [ 44 | // your token serializers 45 | ], 46 | 'key' => [ 47 | 'secret' => 'your-secret', 48 | 'file' => 'your-certificate-file', 49 | ], 50 | ], 51 | ``` 52 | 53 | 2. Setup definitions, required for `\Yiisoft\Auth\Middleware\Authentication` middleware in a config, for example, 54 | in `config/web/auth.php`: 55 | 56 | ```php 57 | /** @var array $params */ 58 | 59 | use Yiisoft\Auth\Jwt\TokenManagerInterface; 60 | use Yiisoft\Auth\Jwt\TokenManager; 61 | use Yiisoft\Auth\AuthenticationMethodInterface; 62 | use Yiisoft\Auth\Jwt\JwtMethod; 63 | 64 | return [ 65 | KeyFactoryInterface::class => [ 66 | 'class' => FromSecret::class, 67 | '__construct()' => [ 68 | $params['yiisoft/auth-jwt']['key']['secret'] 69 | ], 70 | ], 71 | 72 | AuthenticationMethodInterface::class => JwtMethod::class, 73 | ]; 74 | ``` 75 | 76 | > Note: Don't forget to declare your implementations of `\Yiisoft\Auth\IdentityInterface` and `\Yiisoft\Auth\IdentityRepositoryInterface`. 77 | 78 | 3. Use `Yiisoft\Auth\Middleware\Authentication` middleware. 79 | Read more about middlewares in the [middleware guide](https://github.com/yiisoft/docs/blob/master/guide/en/structure/middleware.md). 80 | 81 | ### Configuring independently 82 | 83 | You can configure `Authentication` middleware manually: 84 | 85 | ```php 86 | /** @var \Yiisoft\Auth\IdentityRepositoryInterface $identityRepository */ 87 | $identityRepository = getIdentityRepository(); 88 | 89 | $tokenRepository = $container->get(\Yiisoft\Auth\Jwt\TokenRepositoryInterface::class); 90 | 91 | $authenticationMethod = new \Yiisoft\Auth\Jwt\JwtMethod($identityRepository, $tokenRepository); 92 | 93 | $middleware = new \Yiisoft\Auth\Middleware\Authentication( 94 | $authenticationMethod, 95 | $responseFactory, // PSR-17 ResponseFactoryInterface. 96 | $failureHandler // Optional, \Yiisoft\Auth\Handler\AuthenticationFailureHandler by default. 97 | ); 98 | ``` 99 | 100 | ## Documentation 101 | 102 | - [Internals](docs/internals.md) 103 | 104 | If you need help or have a question, the [Yii Forum](https://forum.yiiframework.com/c/yii-3-0/63) is a good place for 105 | that. You may also check out other [Yii Community Resources](https://www.yiiframework.com/community). 106 | 107 | ## License 108 | 109 | The Yii Auth JWT is free software. It is released under the terms of the BSD License. 110 | Please see [`LICENSE`](./LICENSE.md) for more information. 111 | 112 | Maintained by [Yii Software](https://www.yiiframework.com/). 113 | 114 | ## Support the project 115 | 116 | [![Open Collective](https://img.shields.io/badge/Open%20Collective-sponsor-7eadf1?logo=open%20collective&logoColor=7eadf1&labelColor=555555)](https://opencollective.com/yiisoft) 117 | 118 | ## Follow updates 119 | 120 | [![Official website](https://img.shields.io/badge/Powered_by-Yii_Framework-green.svg?style=flat)](https://www.yiiframework.com/) 121 | [![Twitter](https://img.shields.io/badge/twitter-follow-1DA1F2?logo=twitter&logoColor=1DA1F2&labelColor=555555?style=flat)](https://twitter.com/yiiframework) 122 | [![Telegram](https://img.shields.io/badge/telegram-join-1DA1F2?style=flat&logo=telegram)](https://t.me/yii3en) 123 | [![Facebook](https://img.shields.io/badge/facebook-join-1DA1F2?style=flat&logo=facebook&logoColor=ffffff)](https://www.facebook.com/groups/yiitalk) 124 | [![Slack](https://img.shields.io/badge/slack-join-1DA1F2?style=flat&logo=slack)](https://yiiframework.com/go/slack) 125 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yiisoft/auth-jwt", 3 | "type": "library", 4 | "description": "Yii auth JWT method", 5 | "keywords": [ 6 | "auth", 7 | "jwt", 8 | "middleware", 9 | "psr-15" 10 | ], 11 | "homepage": "https://www.yiiframework.com/", 12 | "license": "BSD-3-Clause", 13 | "support": { 14 | "issues": "https://github.com/yiisoft/auth-jwt/issues?state=open", 15 | "source": "https://github.com/yiisoft/auth-jwt", 16 | "forum": "https://www.yiiframework.com/forum/", 17 | "wiki": "https://www.yiiframework.com/wiki/", 18 | "irc": "ircs://irc.libera.chat:6697/yii", 19 | "chat": "https://t.me/yii3en" 20 | }, 21 | "funding": [ 22 | { 23 | "type": "opencollective", 24 | "url": "https://opencollective.com/yiisoft" 25 | }, 26 | { 27 | "type": "github", 28 | "url": "https://github.com/sponsors/yiisoft" 29 | } 30 | ], 31 | "require": { 32 | "php": "^8.1", 33 | "psr/http-message": "^1.0|^2.0", 34 | "web-token/jwt-library": "^3.3", 35 | "yiisoft/auth": "^3.0", 36 | "yiisoft/http": "^1.2", 37 | "yiisoft/json": "^1.0" 38 | }, 39 | "require-dev": { 40 | "maglnet/composer-require-checker": "^3.8|^4.2", 41 | "nyholm/psr7": "^1.3", 42 | "phpunit/phpunit": "^9.5", 43 | "rector/rector": "^2.0.0", 44 | "roave/infection-static-analysis-plugin": "^1.16", 45 | "spatie/phpunit-watcher": "^1.23", 46 | "vimeo/psalm": "^4.30|^5.21", 47 | "yiisoft/di": "^1.1", 48 | "yiisoft/injector": "^1.1" 49 | }, 50 | "autoload": { 51 | "psr-4": { 52 | "Yiisoft\\Auth\\Jwt\\": "src" 53 | } 54 | }, 55 | "autoload-dev": { 56 | "psr-4": { 57 | "Yiisoft\\Auth\\Jwt\\Tests\\": "tests" 58 | } 59 | }, 60 | "extra": { 61 | "config-plugin-options": { 62 | "source-directory": "config" 63 | }, 64 | "config-plugin": { 65 | "di": "di.php", 66 | "params": "params.php" 67 | } 68 | }, 69 | "config": { 70 | "sort-packages": true, 71 | "allow-plugins": { 72 | "infection/extension-installer": true, 73 | "composer/package-versions-deprecated": true 74 | } 75 | }, 76 | "scripts": { 77 | "test": "phpunit --testdox --no-interaction", 78 | "test-watch": "phpunit-watcher watch" 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /config/di.php: -------------------------------------------------------------------------------- 1 | [ 20 | 'class' => FromSecret::class, 21 | '__construct()' => [$params['yiisoft/auth-jwt']['key']['secret']], 22 | ], 23 | AlgorithmManager::class => static function (Injector $injector) use ($params) { 24 | $algorithms = array_map( 25 | static fn ($algorithm) => is_string($algorithm) ? $injector->make($algorithm) : $algorithm, 26 | $params['yiisoft/auth-jwt']['algorithms'] ?? [] 27 | ); 28 | return $injector->make(AlgorithmManager::class, ['algorithms' => $algorithms]); 29 | }, 30 | JWSSerializerManager::class => static function (Injector $injector) use ($params) { 31 | $serializers = array_map( 32 | static fn ($serializer) => is_string($serializer) ? $injector->make($serializer) : $serializer, 33 | $params['yiisoft/auth-jwt']['serializers'] ?? [] 34 | ); 35 | return $injector->make(JWSSerializerManager::class, ['serializers' => $serializers]); 36 | }, 37 | TokenFactoryInterface::class => TokenFactory::class, 38 | TokenRepositoryInterface::class => TokenRepository::class, 39 | ]; 40 | -------------------------------------------------------------------------------- /config/params.php: -------------------------------------------------------------------------------- 1 | [ 10 | 'algorithms' => [ 11 | HS256::class, 12 | ], 13 | 'serializers' => [ 14 | CompactSerializer::class, 15 | ], 16 | 'key' => [ 17 | 'secret' => '', 18 | 'file' => '', 19 | 'password' => '', 20 | ], 21 | ], 22 | ]; 23 | -------------------------------------------------------------------------------- /infection.json.dist: -------------------------------------------------------------------------------- 1 | { 2 | "source": { 3 | "directories": [ 4 | "src" 5 | ] 6 | }, 7 | "logs": { 8 | "text": "php:\/\/stderr", 9 | "stryker": { 10 | "report": "master" 11 | } 12 | }, 13 | "mutators": { 14 | "@default": true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /psalm.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /rector.php: -------------------------------------------------------------------------------- 1 | paths([ 11 | __DIR__ . '/src', 12 | __DIR__ . '/tests', 13 | ]); 14 | 15 | // register a single rule 16 | $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class); 17 | 18 | // define sets of rules 19 | $rectorConfig->sets([ 20 | LevelSetList::UP_TO_PHP_81, 21 | ]); 22 | }; 23 | -------------------------------------------------------------------------------- /src/JwtMethod.php: -------------------------------------------------------------------------------- 1 | claimCheckers = $claimCheckers ?? [new ExpirationTimeChecker()]; 55 | } 56 | 57 | public function authenticate(ServerRequestInterface $request): ?IdentityInterface 58 | { 59 | $token = $this->getAuthenticationToken($request); 60 | if ($token === null) { 61 | return null; 62 | } 63 | 64 | $claims = $this->tokenRepository->getClaims($token, $name); 65 | if ($claims === null || !isset($claims[$this->identifier])) { 66 | return null; 67 | } 68 | 69 | $this 70 | ->getClaimCheckerManager() 71 | ->check($claims); 72 | return $this->identityRepository->findIdentity((string)$claims[$this->identifier]); 73 | } 74 | 75 | private function getAuthenticationToken(ServerRequestInterface $request): ?string 76 | { 77 | $authHeaders = $request->getHeader($this->headerName); 78 | $authHeader = reset($authHeaders); 79 | if (!empty($authHeader) && preg_match($this->headerTokenPattern, $authHeader, $matches)) { 80 | return $matches[1]; 81 | } 82 | 83 | $token = $request->getQueryParams()[$this->queryParameterName] ?? null; 84 | return is_string($token) ? $token : null; 85 | } 86 | 87 | private function getClaimCheckerManager(): ClaimCheckerManager 88 | { 89 | return new ClaimCheckerManager($this->claimCheckers); 90 | } 91 | 92 | public function challenge(ResponseInterface $response): ResponseInterface 93 | { 94 | return $response->withHeader(Header::WWW_AUTHENTICATE, "{$this->headerName} realm=\"{$this->realm}\""); 95 | } 96 | 97 | /** 98 | * @param string $realm The HTTP authentication realm. 99 | * 100 | * @return self 101 | */ 102 | public function withRealm(string $realm): self 103 | { 104 | $new = clone $this; 105 | $new->realm = $realm; 106 | return $new; 107 | } 108 | 109 | /** 110 | * @param string $headerName Authorization header name. 111 | * 112 | * @return self 113 | */ 114 | public function withHeaderName(string $headerName): self 115 | { 116 | $new = clone $this; 117 | $new->headerName = $headerName; 118 | return $new; 119 | } 120 | 121 | /** 122 | * @param string $headerTokenPattern Regular expression to use for getting a token from authorization header. 123 | * Token value should match first capturing group. 124 | * 125 | * @psalm-param non-empty-string $headerTokenPattern 126 | */ 127 | public function withHeaderTokenPattern(string $headerTokenPattern): self 128 | { 129 | $new = clone $this; 130 | $new->headerTokenPattern = $headerTokenPattern; 131 | return $new; 132 | } 133 | 134 | /** 135 | * @param string $queryParameterName Request parameter name to check for a token. 136 | * 137 | * @return self 138 | */ 139 | public function withQueryParameterName(string $queryParameterName): self 140 | { 141 | $new = clone $this; 142 | $new->queryParameterName = $queryParameterName; 143 | return $new; 144 | } 145 | 146 | /** 147 | * @param string $identifier Identifier to check claims for. 148 | * 149 | * @return self 150 | */ 151 | public function withIdentifier(string $identifier): self 152 | { 153 | $new = clone $this; 154 | $new->identifier = $identifier; 155 | return $new; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/KeyFactory/FromCertificateFile.php: -------------------------------------------------------------------------------- 1 | file, $additionalValues); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/KeyFactory/FromKeyFile.php: -------------------------------------------------------------------------------- 1 | file, $this->password, $additionalValues); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/KeyFactory/FromPKCS12CertificateFile.php: -------------------------------------------------------------------------------- 1 | file, $this->secret, $additionalValues); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/KeyFactory/FromSecret.php: -------------------------------------------------------------------------------- 1 | secret, $additionalValues); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/KeyFactoryInterface.php: -------------------------------------------------------------------------------- 1 | algorithmManager); 34 | $jws = $jwsBuilder->create()->withPayload(Json::encode($payload)); 35 | $jwk = $this->keyFactory->create(); 36 | 37 | foreach ($this->algorithmManager->list() as $algorithm) { 38 | $jws = $jws->addSignature($jwk, ['alg' => $algorithm]); 39 | } 40 | 41 | return $this->serializerManager->serialize($format, $jws->build(), $signatureIndex); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/TokenFactoryInterface.php: -------------------------------------------------------------------------------- 1 | serializerManager->unserialize($token, $format); 38 | } catch (\InvalidArgumentException) { 39 | return null; 40 | } 41 | 42 | $jwk = $this->keyFactory->create(); 43 | 44 | foreach ($this->algorithmManager->list() as $index => $_algorithm) { 45 | /** @var int $index */ 46 | if ($this->verifyToken($jws, $jwk, $index)) { 47 | /** @var array|null */ 48 | return Json::decode($jws->getPayload() ?? ''); 49 | } 50 | } 51 | return null; 52 | } 53 | 54 | private function verifyToken(JWS $jws, JWK $jwk, int $signature = 0): bool 55 | { 56 | return (new JWSVerifier($this->algorithmManager))->verifyWithKey($jws, $jwk, $signature); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/TokenRepositoryInterface.php: -------------------------------------------------------------------------------- 1 |