kelvinmo/simplejwt

PHP的一个简单的JSON Web Token库。

v0.9.2 2024-09-21 07:47 UTC

README

SimpleJWT是用PHP编写的简单JSON Web Token库。

Latest Stable Version CI

特性

  • JSON Web Token RFC7519、JSON Web签名 RFC7515 和JSON Web加密 RFC7516
  • JSON Web密钥 RFC7517
  • COSE密钥对象 RFC9053
  • 签名算法
    • HMAC系列(HS256、HS384、HS512)
    • RSA系列(RS256、RS384、RS512)
    • ECDSA系列(ES256、ES384、ES512)
    • EdDSA
  • 密钥管理算法
    • 密钥协商或直接加密
    • RSAES-PKCS1-v1_5(RSA1_5)
    • RSAES与OAEP(RSA-OAEP、RSA-OAEP-256)
    • AES密钥包装(A128KW、A192KW、A256KW、A128GCMKW、A192GCMKW、A256GCMKW)
    • PBES2(PBES2-HS256+A128KW、PBES2-HS384+A192KW、PBES2-HS512+A256KW)
    • 椭圆曲线Diffie-Hellman(ECDH-ES),包括X25519
  • 内容加密算法
    • AES_CBC_HMAC_SHA2系列(A128CBC-HS256、A192CBC-HS384、A256CBC-HS512)
    • AES GCM系列(A128GCM、A192GCM、A256GCM)

要求

  • PHP 8.0或更高版本
  • gmp扩展
  • hash扩展
  • openssl扩展
  • 用于EdDSA和X25519支持的sodium扩展

安装

您可以通过Composer安装。

composer require kelvinmo/simplejwt

用法

密钥集

用于签名或验证JWT的密钥必须首先添加到密钥集中。您可以通过以下方式添加密钥:

  1. 通过加载一个符合RFC7517的JWK Set对象的JSON对象
$set = new SimpleJWT\Keys\KeySet();
$set->load(file_get_contents('private.json'));
  1. 手动添加密钥
$set = new SimpleJWT\Keys\KeySet();

// JWK format
$key = new SimpleJWT\Keys\RSAKey(file_get_contents('jwk.json'), 'json');

// PEM format - note raw key only, no X.509 certificates
$key = new SimpleJWT\Keys\RSAKey(file_get_contents('rsa.pem'), 'pem');

$set->add($key);
  1. 对于用于HMAC签名的秘密,直接添加
$set = SimpleJWT\Keys\KeySet::createFromSecret('secret123');

// The above is a shortcut for the following:
$set = new SimpleJWT\Keys\KeySet();
$key = new SimpleJWT\Keys\SymmetricKey('secret123', 'bin');
$set->add($key);

创建JWT

要创建JWT,设置所需的头和声明作为单独的数组,然后创建一个JWT对象

// Note $headers['alg'] is required
$headers = ['alg' => 'HS256', 'typ' => 'JWT'];
$claims = ['iss' => 'me', 'exp' => 1234567];
$jwt = new SimpleJWT\JWT($headers, $claims);

然后可以对JWT进行签名和编码

try {
    print $jwt->encode($set);
} catch (\RuntimeException $e) {

}

默认情况下,SimpleJWT将自动在所有JWT中包含一个kid(密钥ID)头和一个iat(发行时间)声明。如果用于签名JWT的密钥未分配kid(例如,如果是从PEM文件导入的),将生成一个kid。您可以通过在调用SimpleJWT\JWT::encode()时将$auto_complete指定为false来禁用此行为。

验证JWT

要消费和验证JWT,请使用解码函数。请注意,您需要提供先前在带外协商的期望alg参数。

try {
    $jwt = SimpleJWT\JWT::decode('abc.def.ghigjghr', $set, 'HS256');
} catch (SimpleJWT\InvalidTokenException $e) {

}

print $jwt->getHeader('alg');
print $jwt->getClaim('sub');

反序列化JWT

您还可以使用反序列化函数不验证地反序列化JWT。请注意,在验证它们之前,您不应信任JWT中包含的数据内容。

try {
    $result = SimpleJWT\JWT::deserialise('abc.def.ghigjghr');
} catch (SimpleJWT\InvalidTokenException $e) {

}

print $result['claims']['sub'];
print $result['signatures'][0]['headers']['alg'];
print $result['signatures'][0]['signing_input'];  // abc.def
print $result['signatures'][0]['signature'];      // ghigjghr
// Additional indices under $result['signatures'] if the JWT has more than
// one signature

创建JWE

要创建JWE,设置所需的头数组和平文,然后创建一个JWE对象

// Note $headers['alg'] and $headers['enc'] are required
$headers = ['alg' => 'PBES2-HS256+A128KW', 'enc' => 'A128CBC-HS256'];
$plaintext = 'This is the plaintext I want to encrypt.';
$jwt = new SimpleJWT\JWE($headers, $plaintext);

然后可以对JWE进行加密

try {
    print $jwt->encrypt($set);
} catch (\RuntimeException $e) {

}

解密JWE

要解密JWE,请使用解密函数

try {
    $jwt = SimpleJWT\JWE::decrypt('abc.def.ghi.klm.nop', $set, 'PBES2-HS256+A128KW');
} catch (SimpleJWT\InvalidTokenException $e) {

}

print $jwt->getHeader('alg');
print $jwt->getPlaintext();

许可证

BSD 3条款