lindelius / php-jwt
Requires
- php: ^7.2||^8.0
- ext-json: *
Requires (Dev)
- ext-openssl: *
- phpbench/phpbench: ^0.17
- phpunit/phpunit: ^8.5
README
PHP 中处理 JSON Web Tokens (JWT) 的便利库。
此库符合 RFC 7519 标准,除了不支持未签名的 JWT("none" 算法)外,还内置了对以下声明的支持
aud
(受众)声明 - 第 4.1.3 节exp
(过期时间)声明 - 第 4.1.4 节iat
(签发时间)声明 - 第 4.1.6 节iss
(发行者)声明 - 第 4.1.1 节nbf
(不可用之前)声明 - 第 4.1.5 节
需求
- PHP 7.2 或更高版本
- OpenSSL PHP 扩展(用于某些算法)
目录
安装
如果您使用的是 Composer,您可以通过在项目的根目录中运行以下命令来安装此库的最新版本
composer require lindelius/php-jwt
您还可以通过导航到“发布”页面并展开最新发布的“资产”部分来手动下载库。
用法
步骤 1. 扩展抽象 JWT
模型并选择一个算法。
use Lindelius\JWT\Algorithm\HMAC\HS256; use Lindelius\JWT\JWT; class MyJWT extends JWT { use HS256; }
步骤 2. 开始创建您的 JWT。
$jwt = MyJWT::create('HS256'); // Include whatever data is required by your use case $jwt->field = 'value'; $jwt->other = ['nested_field' => 'value']; // Let the JWT expire after 20 minutes (optional, but recommended) $jwt->exp = time() + (60 * 20); // Encode the JWT using a key suitable for the chosen algorithm $encodedJwtHash = $jwt->encode('YOUR_HMAC_KEY');
步骤 3. 解码并验证发送回来的 JWT。
$decodedJwt = MyJWT::decode($encodedJwtHash); // The data is available immediately after decode $field = $decodedJwt->field; $other = $decodedJwt->other; // HOWEVER, do NOT forget to verify the data before trusting it $decodedJwt->verify('THE_SAME_HMAC_KEY');
如果您正在使用具有内置支持的任何声明(如 aud
或 iss
),您可以通过将预期值传递给 verify()
方法来验证它们(如下所示)。
$decodedJwt->verify('THE_SAME_HMAC_KEY', [ // Single valid audience 'aud' => 'https://my-application.tld', // Multiple valid issuers 'iss' => ['Expected Issuer', 'Alternate Issuer'], ]);
算法选择
库中当前包含以下算法
- HS256
- HS384
- HS512
- RS256 (需要 OpenSSL 扩展)
- RS384 (需要 OpenSSL 扩展)
- RS512 (需要 OpenSSL 扩展)
您可以通过在 JWT 模型中包含相关的 trait(s) 来使用任何内置算法。
use Lindelius\JWT\Algorithm\RSA\RS256; use Lindelius\JWT\JWT; class MyJWT extends JWT { use RS256; } $jwt = MyJWT::create('RS256');
如果您想使用库中尚未包含的算法,您可以通过实现所需的 encodeWithX()
和 verifyWithX()
方法(与当前包含的 trait 相同的方式)来轻松添加对该算法的支持。
容差时间
如果您的应用程序服务器存在时钟偏差,您可以使用JWT::$leeway
属性,在验证某些声明(如exp
、iat
和nbf
)时,为它们提供几秒钟的额外时间。
强烈建议将宽容时间尽可能保持在最低。
use Lindelius\JWT\JWT; class MyJWT extends JWT { public static $leeway = 60; }
多个加密密钥
如果您的应用程序使用了多个加密密钥,那么您必须以某种方式跟踪每个JWT使用的是哪个密钥。一种方法是在JWT中使用kid
头部字段来包含“密钥ID”。
$availableKeys = [ 'key_1' => 'J5hZTw1vtee0PGaoAuaW', 'key_2' => '8zUpiGcaPkNhNGi8oyrq', 'key_3' => 'RfxRP43BIKoSQ7P1GfeO', ]; // Decide which key to use for the JWT $keyId = 'key_2'; // Include the key ID ("kid") in the JWT's header $jwt = MyJWT::create('HS256'); $jwt->setHeaderField('kid', $keyId); $encodedJwt = $jwt->encode($availableKeys[$keyId]);
如果您使用这种方法,当验证JWT时,您只需向JWT::verify()
方法提供$availableKeys
,它将自动查找并使用正确的密钥。
$decodedJwt = MyJWT::decode($encodedJwt); $decodedJwt->verify($availableKeys);
基准测试
此库使用PHPBench进行基准测试。
您可以从库的根目录运行以下命令,在自己的系统上对库进行基准测试。
./vendor/bin/phpbench run benchmarks/ --report=default