ignislabs/hotjot

无装饰JWT库

1.0.0 2017-11-22 21:28 UTC

This package is not auto-updated.

Last update: 2024-09-15 01:57:48 UTC


README

Build Status Version License

无装饰JWT & JWS库。

安装

使用composer安装

$ composer require ignislabs/hotjot

要求

  • PHP >= 7.1
  • OpenSSL扩展
  • JSON扩展

用法

创建、验证和验证令牌非常简单,在我们更详细地查看每个组件之前,先快速看一下这些操作。

创建令牌

$token = $factory->create($claims, $headers);

验证令牌

$signer->verify($token);

验证令牌

$validator->validate($token);

让我们首先看看签名者,因为这是库中最重要的部分。您需要一个签名者来创建和验证签名令牌。

签名者

您可以选择HMACRSANone签名者。

HMAC签名者

HMAC是最简单的。它是一种对称算法,这意味着您只有一个私钥。您应尽量使其在密码学上尽可能安全且随机。

您有3个不同的选项:HS256HS384HS512。所有这三个选项都只需要一个加密密钥作为构造函数参数。

$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个不同的选项:RS256RS384RS512。所有这三个选项都需要私钥和公钥,以及如果您的私钥受保护,则需要密码。

$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;

令牌创建

现在您已经了解了签名者,让我们看看如何创建令牌。

要创建令牌,您需要FactorySigner,您将获得一个具有一些便捷方法的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对象,同样iatnbf也是如此。

如果出于某种原因您需要使用不同的签名者,您可以这样做

$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