JWT Tokens in C++: jwt-cpp Library
JSON Web Token (JWT) is an open standard (RFC 7519) for creating access tokens based on JSON. In C++, the jwt-cpp library (by Thalhammer) is widely used for working with JWT. It provides a convenient API for creating, verifying, and decoding JWT tokens with support for various signing algorithms (HS256, RS256, etc.).
The library is written in modern C++17, requires no external dependencies (except OpenSSL for asymmetric algorithms), and is actively maintained by the community.
Installing jwt-cpp
The easiest way to install it is via the vcpkg or Conan package manager:
// Via vcpkgvcpkg install jwt-cpp
// Via Conanconan install jwt-cpp/0.7.0@
// Or copy the header file into your projectgit clone https://github.com/Thalhammer/jwt-cpp.gitTo compile with CMake, simply specify:
find_package(jwt-cpp REQUIRED)target_link_libraries(myapp jwt-cpp::jwt-cpp)Main Features
- Token creation with arbitrary claims (sub, iss, exp, custom).
- Verification of signature and lifetime checks (exp, nbf).
- Decoding payload without verification (for debugging).
- Algorithm support: HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512.
- Custom validators — you can add checks for any fields.
Example 1: Creating a JWT Token (HS256)
#include <jwt-cpp/jwt.h>#include <iostream>
int main() { // Create a token with HS256 algorithm 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 << "Created token:" << token << std::endl; return 0;}In this example, we created a token with:
- type JWT,
- issuer
auth.pythonlib.ru, - subject
user123, - expiration time of 1 hour,
- custom field
rolewith valueadmin.
Example 2: Verification and Decoding
#include <jwt-cpp/jwt.h>#include <iostream>
int main() { std::string token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."; // Your token
try { // Decode without signature verification (payload reading only) auto decoded = jwt::decode(token); std::cout << "Issuer: " << decoded.get_issuer() << std::endl; std::cout << "Subject: " << decoded.get_subject() << std::endl;
// Verify signature and lifetime auto verifier = jwt::verify() .allow_algorithm(jwt::algorithm::hs256{"secret_key_12345"}) .with_issuer("auth.pythonlib.ru");
verifier.verify(decoded); std::cout << "Token is valid!" << std::endl;
} catch (const jwt::TokenExpiredError& e) { std::cerr << "Error: token expired" << std::endl; } catch (const jwt::InvalidAlgorithmError& e) { std::cerr << "Error: invalid algorithm" << std::endl; } catch (const std::exception& e) { std::cerr << "Verification error: " << e.what() << std::endl; }
return 0;}Example 3: Working with Asymmetric Keys (RS256)
#include <jwt-cpp/jwt.h>#include <fstream>#include <sstream>
std::string read_file(const std::string& path) {