C++中的JWT令牌:jwt-cpp库
JSON Web Token (JWT) 是一种基于JSON的开放标准(RFC 7519),用于创建访问令牌。在C++中,jwt-cpp库(作者Thalhammer)被广泛用于处理JWT。它提供了方便的API,用于创建、验证和解码JWT令牌,并支持多种签名算法(如HS256、RS256等)。
该库使用现代C++17编写,无需外部依赖(除OpenSSL用于非对称算法外),并得到社区的积极维护。
安装jwt-cpp
最简单的安装方式是通过包管理器vcpkg或Conan:
// 通过vcpkgvcpkg install jwt-cpp
// 通过Conanconan install jwt-cpp/0.7.0@
// 或者将头文件复制到项目中git clone https://github.com/Thalhammer/jwt-cpp.git使用CMake编译时,只需指定:
find_package(jwt-cpp REQUIRED)target_link_libraries(myapp jwt-cpp::jwt-cpp)主要功能
- 创建令牌,支持自定义声明(sub、iss、exp、自定义)。
- 验证签名并检查有效期(exp、nbf)。
- 解码载荷(无需验证,用于调试)。
- 支持的算法:HS256、HS384、HS512、RS256、RS384、RS512、ES256、ES384、ES512。
- 自定义验证器——可以添加对任意字段的检查。
示例1:创建JWT令牌(HS256)
#include <jwt-cpp/jwt.h>#include <iostream>
int main() { // 使用HS256算法创建令牌 auto token = jwt::create() .set_type("JWT") .set_issuer("auth.pythonlib.ru") .set_subject("user123") .set_expires_at(std::chrono::system_clock::now() + std::chrono::hours{1}) .set_payload_claim("role", jwt::claim(std::string("admin"))) .sign(jwt::algorithm::hs256{"secret_key_12345"});
std::cout << "创建的令牌:" << token << std::endl; return 0;}在此示例中,我们创建了一个令牌,包含:
- 类型为JWT,
- 发行者为
auth.pythonlib.ru, - 主题为
user123, - 有效期为1小时,
- 自定义字段
role,值为admin。
示例2:验证和解码
#include <jwt-cpp/jwt.h>#include <iostream>
int main() { std::string token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."; // 您的令牌
try { // 解码而不验证签名(仅用于读取载荷) auto decoded = jwt::decode(token); std::cout << "发行者: " << decoded.get_issuer() << std::endl; std::cout << "主题: " << decoded.get_subject() << std::endl;
// 验证签名和有效期 auto verifier = jwt::verify() .allow_algorithm(jwt::algorithm::hs256{"secret_key_12345"}) .with_issuer("auth.pythonlib.ru");
verifier.verify(decoded); std::cout << "令牌有效!" << std::endl;
} catch (const jwt::TokenExpiredError& e) { std::cerr << "错误:令牌已过期" << std::endl; } catch (const jwt::InvalidAlgorithmError& e) { std::cerr << "错误:无效算法" << std::endl; } catch (const std::exception& e) { std::cerr << "验证错误:" << e.what() << std::endl; }
return 0;}示例3:使用非对称密钥(RS256)
#include <jwt-cpp/jwt.h>#include <fstream>#include <sstream>
std::string read_file(const std::string& path) {