ignislabs / hotjot
无装饰JWT库
Requires
- php: >=7.1
- ext-json: *
- ext-openssl: *
Requires (Dev)
- phpspec/phpspec: ^4.1
This package is not auto-updated.
Last update: 2024-09-15 01:57:48 UTC
README
无装饰JWT & JWS库。
安装
使用composer安装
$ composer require ignislabs/hotjot
要求
- PHP >= 7.1
- OpenSSL扩展
- JSON扩展
用法
创建、验证和验证令牌非常简单,在我们更详细地查看每个组件之前,先快速看一下这些操作。
创建令牌
$token = $factory->create($claims, $headers);
验证令牌
$signer->verify($token);
验证令牌
$validator->validate($token);
让我们首先看看签名者,因为这是库中最重要的部分。您需要一个签名者来创建和验证签名令牌。
签名者
您可以选择HMAC
、RSA
或None
签名者。
HMAC
签名者
HMAC是最简单的。它是一种对称算法,这意味着您只有一个私钥。您应尽量使其在密码学上尽可能安全且随机。
您有3个不同的选项:HS256
、HS384
和HS512
。所有这三个选项都只需要一个加密密钥作为构造函数参数。
$signer = new \IgnisLabs\HotJot\Signer\HMAC\HS512('encryption key');
RSA
签名者
RSA是非对称的,这意味着您需要创建一个密钥对
# create a strong, password protected private key $ openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -outform PEM -out private.pem -pass stdin # get public key $ openssl rsa -pubout -in private.pem -out public.pem
如果您不想生成受密码保护的密钥,只需省略-pass stdin
。
如果您需要/想要,可以使您的公钥公开可用,以便任何人都可以使用它来验证令牌是否确实由您签署(这是公钥密码学背后的一个目的)。
同样,您有3个不同的选项:RS256
、RS384
和RS512
。所有这三个选项都需要私钥和公钥,以及如果您的私钥受保护,则需要密码。
$privateKey = file_get_contents('/path/to/private.pem'); $publicKey = file_get_contents('/path/to/public.pem'); $signer = new \IgnisLabs\HotJot\Signer\RSA\RS512($privateKey, $publicKey, 'key passphrase (if any)');
私钥用于签名,而公钥用于验证。
None
签名者
使用None
签名者将导致一个未加密的令牌,没有签名,并且使用此签名者进行验证将始终失败,因为未加密的令牌没有签名。
警告!虽然您技术上可以创建未加密的令牌,但您应该非常小心,并且非常清楚自己在做什么。
此签名者不需要任何参数,因为它不能签名或验证。它将始终返回一个空字符串作为签名,并且验证将始终失败。
$signer = new \IgnisLabs\HotJot\Signer\None;
令牌创建
现在您已经了解了签名者,让我们看看如何创建令牌。
要创建令牌,您需要Factory
和Signer
,您将获得一个具有一些便捷方法的Token
对象。
创建受保护令牌
要创建受保护令牌,请使用任何签名者,但不能使用None
。
$signer = new \IgnisLabs\HotJot\Signer\HMAC\HS512('encryption key'); $factory = new \IgnisLabs\HotJot\Factory($signer); $token = $factory->create([ 'iss' => 'http://api.example.com', 'aud' => 'http://www.example.com', 'jti' => bin2hex(random_bytes(16)), 'exp' => (new DateTime('+10 days'))->getTimestamp(), // etc... ]); $token->getHeader('alg'); // -> 'HS512' $token->getClaim('iss'); // -> 'http://api.example.com' $token->getClaim('exp'); // -> DateTime object
如您所见,exp
返回一个DateTime
对象,同样iat
和nbf
也是如此。
如果出于某种原因您需要使用不同的签名者,您可以这样做
$newFactory = $factory->setSigner($anotherSigner);
工厂是不可变的,因此当您这样做时,当前的工厂实例不会被修改,而是返回一个新的实例,具有新的签名者。
这在您想要临时更改特殊用例的签名时很有用。
创建未受保护令牌
要创建未受保护的令牌,您需要使用None
签名者。
警告!虽然您技术上可以创建未受保护的令牌,但您应该非常小心,并且非常清楚自己在做什么。(是的,我知道我在重复:P)
$signer = new \IgnisLabs\HotJot\Signer\None; $factory = new \IgnisLabs\HotJot\Factory($signer); $token = $factory->create([ 'iss' => 'http://api.example.com', 'aud' => 'http://www.example.com', 'jti' => bin2hex(random_bytes(16)), 'exp' => (new DateTime('+10 days'))->getTimestamp(), // etc... ]); $token->getClaim('alg'); // -> 'none' $token->getSignature(); // -> null
解析
您可以使用解析器解析编码的令牌字符串。如何获取编码的令牌不在库的范围内(授权头、查询参数等)。
解析编码的令牌时,您将得到一个 Token
对象,与使用 Factory
一样。
$parser = new \IgnisLabs\HotJot\Parser; $token = $parser->parse($encodedTokenString);
解析器 不验证或验证令牌,只要它可以解析并且遵循 rfc 标准,解析器就会成功并返回令牌对象。您需要使用签名者和验证者来验证和验证令牌。
如果解析器失败,它将抛出带有适当消息的 InvalidTokenException
。
签名验证
当从外部世界接收令牌时,这是一个关键步骤。
此库不会根据 alg
头自动设置任何算法,您也不应该这样做。遵循此简单规则可以避免 已知的漏洞。
此库通过要求您自己实例化所需的签名者,并在实例化时通过传递密钥而不是在验证时传递密钥,以硬关联密钥和签名者,从而使其更容易避免此类漏洞。
所有签名者首先会检查令牌的 alg
头,并检查它是否与签名者的算法匹配。如果算法不匹配,它将抛出 SignatureVerificationException
异常。
$signer = new \IgnisLabs\HotJot\Signer\RSA\RS512($privateKey, $publicKey, 'passphrase'); $signer->verify($token); // -> boolean — $token most likely obtained through the parser
验证
一旦您有一个已验证的令牌,您就可以使用 Validator
开始验证它。
Validator
是一个非常简单的类,它接受一些令牌验证器并将它们用于验证令牌。验证器在失败时不返回任何值,而是抛出异常。
此库已经包含一些有用的验证器,但您可以添加尽可能多的验证器。
use IgnisLabs\HotJot\Validators as 🕵; $validator = new \IgnisLabs\HotJot\Validator( new 🕵\IssuedAtValidator, // fails if token used before `iat` new 🕵\NotBeforeValidator, // fails if token used before `nbf` new 🕵\ExpiresAtValidator // fails if token is used after `exp` ); $validator->validate($token);
如果您想强制要求任何这些验证器,可以像这样实例化它们
use IgnisLabs\HotJot\Validators as 🕵; $validator = new \IgnisLabs\HotJot\Validator( new 🕵\IssuedAtValidator(true), new 🕵\NotBeforeValidator(true), new 🕵\ExpiresAtValidator(true) ); $validator->validate($token);
您可以创建自己的验证器,只需实现 IgnisLabs\HotJot\Contracts\TokenValidator
接口即可。您还有 \IgnisLabs\HotJot\Validators\ClaimRequiredTrait
可用,以在创建必需验证器时节省时间。
算法
✔️ none
✔️ HS256
✔️ HS384
✔️ HS512
✔️ RS256
✔️ RS384
✔️ RS512
🔲 ES256
🔲 ES384
🔲 ES512