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

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

使用 JWT 密钥 token 299    来源:    2025-03-11

namshi/jose 是一个用于生成和验证 JSON Web Tokens (JWT) 的 PHP 库。它支持多种签名算法,并且易于使用。以下是如何使用 namshi/jose 库来安全地生成和验证 JWT 的步骤。

1. 安装 namshi/jose

首先,你需要通过 Composer 安装 namshi/jose 库。如果你还没有 Composer,请先安装它。

composer require namshi/jose

2. 生成 JWT

生成 JWT 的过程包括创建一个包含有效载荷(payload)的 JWT,并使用一个密钥对其进行签名。

use Namshi\JOSE\SimpleJWS;

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

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

// 使用密钥对 JWT 进行签名
$privateKey = 'your-secret-key'; // 请确保使用一个安全的密钥
$jws->sign($privateKey);

// 获取生成的 JWT
$token = $jws->getTokenString();
echo $token;

3. 验证 JWT

验证 JWT 的过程包括解析 JWT,检查签名是否有效,并验证有效载荷中的声明(如过期时间)。

use Namshi\JOSE\SimpleJWS;

// 假设你从请求中获取到了 JWT
$token = 'your-jwt-token';

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

    // 使用相同的密钥验证签名
    $publicKey = 'your-secret-key'; // 使用与签名时相同的密钥
    if ($jws->isValid($publicKey, 'HS256')) {
        // 获取有效载荷
        $payload = $jws->getPayload();

        // 检查 JWT 是否过期
        if (isset($payload['exp']) && $payload['exp'] < time()) {
            throw new Exception('Token has expired.');
        }

        // 验证通过,可以继续处理
        echo "Token is valid!";
        print_r($payload);
    } else {
        throw new Exception('Invalid token signature.');
    }
} catch (Exception $e) {
    echo 'Token validation failed: ' . $e->getMessage();
}

4. 安全注意事项

  1. 密钥管理:确保你的密钥是安全的,并且不要将其硬编码在代码中。可以考虑使用环境变量或密钥管理服务来存储密钥。

  2. 算法选择:根据你的安全需求选择合适的签名算法。HS256 是一个常用的对称加密算法,但如果你需要更高的安全性,可以考虑使用非对称加密算法如 RS256

  3. 过期时间:始终为 JWT 设置一个合理的过期时间,以防止令牌被长期滥用。

  4. 防止重放攻击:可以考虑在有效载荷中添加一个 jti(JWT ID)字段,并在服务器端维护一个已使用令牌的黑名单,以防止重放攻击。

  5. HTTPS:确保 JWT 在传输过程中使用 HTTPS 加密,以防止中间人攻击。

5. 使用非对称加密算法(可选)

如果你需要使用非对称加密算法(如 RS256),你可以使用以下代码生成和验证 JWT。

生成 JWT

use Namshi\JOSE\SimpleJWS;

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

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

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

// 获取生成的 JWT
$token = $jws->getTokenString();
echo $token;

验证 JWT

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 = $jws->getPayload();

        // 检查 JWT 是否过期
        if (isset($payload['exp']) && $payload['exp'] < time()) {
            throw new Exception('Token has expired.');
        }

        // 验证通过,可以继续处理
        echo "Token is valid!";
        print_r($payload);
    } else {
        throw new Exception('Invalid token signature.');
    }
} catch (Exception $e) {
    echo 'Token validation failed: ' . $e->getMessage();
}

总结

namshi/jose 库提供了一个简单而强大的方式来生成和验证 JWT。通过遵循上述步骤和注意事项,你可以确保你的 JWT 实现是安全可靠的。