插件窝 干货文章 安全可靠的JWT签名与验证:使用namshi/jose库

安全可靠的JWT签名与验证:使用namshi/jose库

JWT 密钥 签名 使用 173    来源:    2025-03-14

namshi/jose 是一个用于处理 JSON Web Tokens (JWT) 的 PHP 库。它支持 JWT 的签名、验证、加密和解密操作。为了确保 JWT 的安全性和可靠性,以下是如何使用 namshi/jose 库进行 JWT 的签名与验证的详细步骤。

1. 安装 namshi/jose

首先,你需要通过 Composer 安装 namshi/jose 库:

composer require namshi/jose

2. 创建 JWT 并进行签名

在创建 JWT 时,你需要选择一个合适的签名算法(如 HS256RS256 等),并使用一个安全的密钥进行签名。

use Namshi\JOSE\SimpleJWS;

// 创建一个 JWT
$jws = new SimpleJWS([
    'alg' => 'HS256', // 使用 HMAC SHA-256 算法
]);

// 设置 JWT 的 payload
$jws->setPayload([
    'uid' => 12345,
    'username' => 'john_doe',
    'exp' => time() + 3600, // 设置过期时间为 1 小时后
]);

// 使用密钥进行签名
$secretKey = 'your-secret-key'; // 请确保密钥足够复杂且安全
$jws->sign($secretKey);

// 获取签名的 JWT
$token = $jws->getTokenString();
echo "JWT: " . $token . "\n";

3. 验证 JWT

在验证 JWT 时,你需要使用相同的密钥和算法来验证签名的有效性,并检查 JWT 是否已过期。

use Namshi\JOSE\SimpleJWS;

// 从请求中获取 JWT
$token = 'your-jwt-token';

try {
    // 解析 JWT
    $jws = SimpleJWS::load($token);

    // 验证签名
    if ($jws->isValid('your-secret-key', 'HS256')) {
        // 获取 payload
        $payload = $jws->getPayload();

        // 检查 JWT 是否已过期
        if (isset($payload['exp']) && $payload['exp'] >= time()) {
            echo "JWT 验证成功!\n";
            print_r($payload);
        } else {
            echo "JWT 已过期!\n";
        }
    } else {
        echo "JWT 签名验证失败!\n";
    }
} catch (\Exception $e) {
    echo "JWT 解析失败: " . $e->getMessage() . "\n";
}

4. 使用非对称加密算法(如 RS256)

如果你需要使用非对称加密算法(如 RS256),你需要生成一对 RSA 密钥对,并使用私钥进行签名,公钥进行验证。

生成 RSA 密钥对

openssl genrsa -out private.key 2048
openssl rsa -in private.key -pubout -out public.key

使用 RS256 进行签名

use Namshi\JOSE\SimpleJWS;

// 创建一个 JWT
$jws = new SimpleJWS([
    'alg' => 'RS256', // 使用 RSA SHA-256 算法
]);

// 设置 JWT 的 payload
$jws->setPayload([
    'uid' => 12345,
    'username' => 'john_doe',
    'exp' => time() + 3600, // 设置过期时间为 1 小时后
]);

// 使用私钥进行签名
$privateKey = file_get_contents('path/to/private.key');
$jws->sign($privateKey);

// 获取签名的 JWT
$token = $jws->getTokenString();
echo "JWT: " . $token . "\n";

使用 RS256 进行验证

use Namshi\JOSE\SimpleJWS;

// 从请求中获取 JWT
$token = 'your-jwt-token';

try {
    // 解析 JWT
    $jws = SimpleJWS::load($token);

    // 使用公钥验证签名
    $publicKey = file_get_contents('path/to/public.key');
    if ($jws->isValid($publicKey, 'RS256')) {
        // 获取 payload
        $payload = $jws->getPayload();

        // 检查 JWT 是否已过期
        if (isset($payload['exp']) && $payload['exp'] >= time()) {
            echo "JWT 验证成功!\n";
            print_r($payload);
        } else {
            echo "JWT 已过期!\n";
        }
    } else {
        echo "JWT 签名验证失败!\n";
    }
} catch (\Exception $e) {
    echo "JWT 解析失败: " . $e->getMessage() . "\n";
}

5. 安全建议

  1. 密钥管理:确保密钥的安全性,不要将密钥硬编码在代码中,最好使用环境变量或密钥管理服务来存储密钥。
  2. 算法选择:根据安全需求选择合适的签名算法。对于高安全性要求的场景,推荐使用非对称加密算法(如 RS256)。
  3. 过期时间:始终为 JWT 设置合理的过期时间,避免 JWT 被长期滥用。
  4. HTTPS:在传输 JWT 时,确保使用 HTTPS 来防止中间人攻击。

通过以上步骤,你可以使用 namshi/jose 库安全可靠地进行 JWT 的签名与验证。