qeq66 / jwt
一个用于处理 JSON Web Token 和 JSON Web Signature 的简单库
4.1.5
2021-09-28 19:34 UTC
Requires
- php: ^7.4 || ^8.0
- ext-hash: *
- ext-json: *
- ext-mbstring: *
- ext-openssl: *
- ext-sodium: *
- lcobucci/clock: ^2.0
Requires (Dev)
- infection/infection: ^0.21
- lcobucci/coding-standard: ^6.0
- mikey179/vfsstream: ^1.6.7
- phpbench/phpbench: ^1.0
- phpstan/extension-installer: ^1.0
- phpstan/phpstan: ^0.12
- phpstan/phpstan-deprecation-rules: ^0.12
- phpstan/phpstan-phpunit: ^0.12
- phpstan/phpstan-strict-rules: ^0.12
- phpunit/php-invoker: ^3.1
- phpunit/phpunit: ^9.5
- 4.1.5
- 4.1.4
- 4.1.3
- 4.1.2
- 4.1.1
- 4.1.0
- 4.0.4
- 4.0.3
- 4.0.2
- 4.0.1
- 4.0.0
- 4.0.0-beta1
- 4.0.0-alpha3
- 4.0.0-alpha2
- 4.0.0-alpha1
- 3.4.6
- 3.4.5
- 3.4.4
- 3.4.3
- 3.4.2
- 3.4.1
- 3.4.0
- 3.3.x-dev
- 3.3.5
- 3.3.4
- 3.3.3
- 3.3.2
- 3.3.1
- 3.3.0
- 3.2.5
- 3.2.4
- 3.2.3
- 3.2.2
- 3.2.1
- 3.2.0
- 3.1.2
- 3.1.1
- 3.1.0
- 3.0.5
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.0
- 1.1.0
- 1.0.2
- 1.0.1
- 1.0.0
This package is not auto-updated.
Last update: 2024-09-17 16:26:58 UTC
README
一个用于处理 JSON Web Token 和 JSON Web Signature 的简单库(需要 PHP 5.6+)。实现基于RFC 7519。
安装
该包在Packagist上可用,您可以使用Composer安装它。
composer require lcobucci/jwt
依赖项
- PHP 5.6+
- OpenSSL 扩展
基本用法
创建
只需使用构建器创建新的 JWT/JWS 令牌
use Lcobucci\JWT\Builder; $time = time(); $token = (new Builder())->issuedBy('http://example.com') // Configures the issuer (iss claim) ->permittedFor('http://example.org') // Configures the audience (aud claim) ->identifiedBy('4f1g23a12aa', true) // Configures the id (jti claim), replicating as a header item ->issuedAt($time) // Configures the time that the token was issue (iat claim) ->canOnlyBeUsedAfter($time + 60) // Configures the time that the token can be used (nbf claim) ->expiresAt($time + 3600) // Configures the expiration time of the token (exp claim) ->withClaim('uid', 1) // Configures a new claim, called "uid" ->getToken(); // Retrieves the generated token $token->getHeaders(); // Retrieves the token headers $token->getClaims(); // Retrieves the token claims echo $token->getHeader('jti'); // will print "4f1g23a12aa" echo $token->getClaim('iss'); // will print "http://example.com" echo $token->getClaim('uid'); // will print "1" echo $token; // The string representation of the object is a JWT string (pretty easy, right?)
从字符串解析
使用解析器从 JWT 字符串创建新的令牌(使用之前的令牌作为示例)
use Lcobucci\JWT\Parser; $token = (new Parser())->parse((string) $token); // Parses from a string $token->getHeaders(); // Retrieves the token header $token->getClaims(); // Retrieves the token claims echo $token->getHeader('jti'); // will print "4f1g23a12aa" echo $token->getClaim('iss'); // will print "http://example.com" echo $token->getClaim('uid'); // will print "1"
验证
我们可以轻松验证令牌是否有效(使用之前的令牌和时间作为示例)
use Lcobucci\JWT\ValidationData; $data = new ValidationData(); // It will use the current time to validate (iat, nbf and exp) $data->setIssuer('http://example.com'); $data->setAudience('http://example.org'); $data->setId('4f1g23a12aa'); var_dump($token->validate($data)); // false, because token cannot be used before now() + 60 $data->setCurrentTime($time + 61); // changing the validation time to future var_dump($token->validate($data)); // true, because current time is between "nbf" and "exp" claims $data->setCurrentTime($time + 4000); // changing the validation time to future var_dump($token->validate($data)); // false, because token is expired since current time is greater than exp // We can also use the $leeway parameter to deal with clock skew (see notes below) // If token's claimed time is invalid but the difference between that and the validation time is less than $leeway, // then token is still considered valid $dataWithLeeway = new ValidationData($time, 20); $dataWithLeeway->setIssuer('http://example.com'); $dataWithLeeway->setAudience('http://example.org'); $dataWithLeeway->setId('4f1g23a12aa'); var_dump($token->validate($dataWithLeeway)); // false, because token can't be used before now() + 60, not within leeway $dataWithLeeway->setCurrentTime($time + 51); // changing the validation time to future var_dump($token->validate($dataWithLeeway)); // true, because current time plus leeway is between "nbf" and "exp" claims $dataWithLeeway->setCurrentTime($time + 3610); // changing the validation time to future but within leeway var_dump($token->validate($dataWithLeeway)); // true, because current time - 20 seconds leeway is less than exp $dataWithLeeway->setCurrentTime($time + 4000); // changing the validation time to future outside of leeway var_dump($token->validate($dataWithLeeway)); // false, because token is expired since current time is greater than exp
重要
- 您必须配置
ValidationData
以告知所有要验证的声明。 - 如果
ValidationData
包含未在令牌中使用的声明或令牌包含未在ValidationData
中配置的声明,则它们将被Token::validate()
忽略。 exp
、nbf
和iat
声明默认在ValidationData::__construct()
中配置为当前 UNIX 时间(time()
)。ValidationData
的可选$leeway
参数将在验证基于时间的声明时使用该数量的秒数。对于 "发行时间"(《iat》)和 "在此之前"(《nbf》)声明,我们假装它们在将来;对于 "过期时间"(《exp》)声明,我们假装它们在过去。这允许出现发行服务器和验证服务器时钟不同的情况,如RFC 7519第4.1节所述。
令牌签名
我们可以使用签名来验证令牌在生成后是否未被修改。此库实现了 Hmac、RSA 和 ECDSA 签名(使用 256、384 和 512)。
重要
不要允许发送给解析器的字符串指定要使用的签名算法,否则您的应用程序将容易受到关键的 JWT 安全漏洞的攻击。
下面的示例是安全的,因为 Signer
的选择是硬编码的,不能被恶意用户影响。
Hmac
Hmac 签名非常简单易用
use Lcobucci\JWT\Builder; use Lcobucci\JWT\Signer\Key; use Lcobucci\JWT\Signer\Hmac\Sha256; $signer = new Sha256(); $time = time(); $token = (new Builder())->issuedBy('http://example.com') // Configures the issuer (iss claim) ->permittedFor('http://example.org') // Configures the audience (aud claim) ->identifiedBy('4f1g23a12aa', true) // Configures the id (jti claim), replicating as a header item ->issuedAt($time) // Configures the time that the token was issue (iat claim) ->canOnlyBeUsedAfter($time + 60) // Configures the time that the token can be used (nbf claim) ->expiresAt($time + 3600) // Configures the expiration time of the token (exp claim) ->withClaim('uid', 1) // Configures a new claim, called "uid" ->getToken($signer, new Key('testing')); // Retrieves the generated token var_dump($token->verify($signer, 'testing 1')); // false, because the key is different var_dump($token->verify($signer, 'testing')); // true, because the key is the same
RSA 和 ECDSA
RSA 和 ECDSA 签名基于公钥和私钥,因此您必须使用私钥生成并使用公钥验证
use Lcobucci\JWT\Builder; use Lcobucci\JWT\Signer\Key; use Lcobucci\JWT\Signer\Rsa\Sha256; // you can use Lcobucci\JWT\Signer\Ecdsa\Sha256 if you're using ECDSA keys $signer = new Sha256(); $privateKey = new Key('file://{path to your private key}'); $time = time(); $token = (new Builder())->issuedBy('http://example.com') // Configures the issuer (iss claim) ->permittedFor('http://example.org') // Configures the audience (aud claim) ->identifiedBy('4f1g23a12aa', true) // Configures the id (jti claim), replicating as a header item ->issuedAt($time) // Configures the time that the token was issue (iat claim) ->canOnlyBeUsedAfter($time + 60) // Configures the time that the token can be used (nbf claim) ->expiresAt($time + 3600) // Configures the expiration time of the token (exp claim) ->withClaim('uid', 1) // Configures a new claim, called "uid" ->getToken($signer, $privateKey); // Retrieves the generated token $publicKey = new Key('file://{path to your public key}'); var_dump($token->verify($signer, $publicKey)); // true when the public key was generated by the private one =)
重要的是要说,如果您正在使用 RSA 密钥,则不应调用 ECDSA 签名者(反之亦然),否则 sign()
和 verify()
将引发异常!