jwt-cpp
repository·master·Indexed 22 days ago
https://github.com/thalhammer/jwt-cppA header-only C++11 library for creating, parsing, and verifying JSON Web Tokens (JWT) according to RFC 7519. It supports a wide range of signature algorithms including HMAC (HS256, HS384, HS512), RSA (RS256, RS384, RS512), ECDSA, PSS, and EdDSA, with the ability to implement custom algorithms. The library is designed to be JSON-library agnostic via a traits system and is compatible with OpenSSL, LibreSSL, and wolfSSL.
What's inside jwt-cpp
- jwt-cpp is a header-only C++11 library designed for creating and validating JSON Web Tokens (JWT) according to RFC 7519. It is designed to be versatile and easily integrated with other libraries through a modular architecture.
How JSON Traits work in jwt-cpp
masterJSON Traits define the compatibility mapping between
jwt-cppand a specific JSON library implementation. Becausejwt-cppis designed to be library-agnostic, it uses these traits to understand how to interact with your chosen JSON library's types, how to parse strings into JSON objects, and how to serialize JSON objects back into strings.When using
jwt-cpp, you must pass the traits class as a template parameter to core functions likejwt::create<traits>(),jwt::decode<traits>(), andjwt::verify<traits>().using traits = jwt::traits::nlohmann_json; const auto token = jwt::create<traits>() .set_issuer("auth.mydomain.io") .sign(jwt::algorithm::hs256{"secret"}); const auto decoded = jwt::decode<traits>(token);Security considerations for JWT claims
masterJWTs generated by this library are encoded but not encrypted. While the signature ensures integrity (preventing unauthorized modification), the payload is readable by anyone who has the token.
Do not store confidential or sensitive information directly in JWT claims.
If you need to include sensitive data, the recommended pattern is to generate a random ID, store the sensitive data on your server, and include only that ID in the JWT claims to look up the data when needed.
Configure JSON library via Traits
masterjwt-cpp does not force a specific JSON library. Instead, it uses a templated
jwt::basic_claimthat relies on a type trait to map semantic JSON types (objects, arrays, strings, etc.). You can use provided traits or implement your own to integrate your preferred JSON library.To use your own JSON library, pass your custom traits to
jwt::basic_claim:jwt::basic_claim<my_favorite_json_library_traits> claim(json::object({{"json", true},{"example", 0}}));Implement custom signature algorithms
masterThe
jwt-cpplibrary allows you to implement and use your own signature algorithms by defining a struct that satisfies a specific interface. Your implementation must providesign,verify, andnamemethods.To implement a custom algorithm:
- Define a
structcontaining:std::string sign(const std::string& /*unused*/, std::error_code& ec) const: Performs the signing logic. You must clear the error code (ec.clear()) before performing your operation.void verify(const std::string& /*unused*/, const std::string& signature, std::error_code& ec) const: Validates the signature. If verification fails, setecto an appropriate error code.std::string name() const: Returns the unique string identifier for your algorithm.
- Pass an instance of your struct to the
.sign()method during token creation.
struct your_algorithm{ std::string sign(const std::string& /*unused*/, std::error_code& ec) const { ec.clear(); // CALL YOUR METHOD HERE return {}; } void verify(const std::string& /*unused*/, const std::string& signature, std::error_code& ec) const { ec.clear(); if (!signature.empty()) { ec = error::signature_verification_error::invalid_signature; } // CALL YOUR METHOD HERE } std::string name() const { return "your_algorithm"; } }; // Usage: auto token = jwt::create() .set_id("custom-algo-example") .set_issued_now() .set_expires_in(std::chrono::seconds{36000}) .set_payload_claim("sample", jwt::claim(std::string{"test"})) .sign(your_algorithm{/* parameters */});- Define a
Install jwt-cpp dependencies
masterTo use jwt-cpp, ensure your environment meets the following requirements:
- libcrypto (OpenSSL or compatible)
- libssl-dev (for header files)
- A compiler supporting at least C++11
- Basic STL support
If you are building the included test cases, you also need:
- gtest
- pthread
Use jwt-cpp as a header-only library
masterYou can use
jwt-cppas a header-only library by downloading theinclude/directory.Requirements:
- Ensure the
jwt-cpp/subdirectory is visible during compilation. - You must correctly link to OpenSSL or an alternative cryptography library.
- If you wish to use your own JSON traits implementation, you must define the following macros:
JWT_DISABLE_BASE64JWT_DISABLE_PICOJSON
Refer to
traits.mdfor details on providing custom JSON traits.- Ensure the
Select a cryptography library via CMake
masterWhen configuring the project with CMake, you can choose which underlying SSL/TLS library to use for cryptographic operations. By default, the project uses OpenSSL.
You can explicitly select one of the following libraries by setting the
JWT_SSL_LIBRARYCMake variable:OpenSSL(Default)LibreSSLwolfSSL
Important Note on Linking: Since
jwt-cpprelies on the OpenSSL API, bothLibreSSLandwolfSSLrequire their respective compatibility layers. Ensure that your application only includes one SSL library during compilation to avoid missing symbol errors during the linking stage.cmake . -DJWT_SSL_LIBRARY:STRING=wolfSSLInstall jwt-cpp using a package manager
masterIt is strongly recommended to use a package manager to handle the dependencies for cryptography and JSON libraries. You can find
jwt-cpprecipes for the following package managers:- Conan: https://conan.io/center/recipes/jwt-cpp
- vcpkg: https://vcpkg.link/ports/jwt-cpp
- Nuget: https://www.nuget.org/packages/jwt-cpp/
- Hunter: https://hunter.readthedocs.io/en/latest/packages/pkg/jwt-cpp.html
- Spack: https://packages.spack.io/package.html?name=jwt-cpp
- Xrepo: https://xrepo.xmake.io/#/packages/linux?id=jwt-cpp-linux
Integrate jwt-cpp using CMake find_package
masterThe recommended way to use
jwt-cppin a CMake project is viafind_package.Prerequisites:
- Ensure OpenSSL is installed on your environment.
Installation Steps:
- Configure and build the library:
cmake . cmake --build . cmake --install .- In your own project's
CMakeLists.txt, usefind_packageand link against thejwt-cpp::jwt-cpptarget:
find_package(jwt-cpp CONFIG REQUIRED) target_link_libraries(my_app PRIVATE jwt-cpp::jwt-cpp)Requirements for running Traits examples
masterThe examples located in the
example/traits/directory require an upstream CMake installation to function.Note the following specific dependency requirements for header discovery:
- Boost.JSON: Headers must be located using a custom CMake configuration.
- PicoJSON: Headers must be located using a custom CMake configuration.
Select a pre-built JSON library trait
masterFor convenience,
jwt-cppprovides built-in trait implementations for several popular JSON libraries. To use one, include its specific header and pass it as a template argument to thejwtnamespace functions.Supported libraries include:
picojson(Note:picojsonis used by default for specializedjwt::claimhelpers. DefineJWT_DISABLE_PICOJSONto remove this dependency.)nlohmann-jsonjsonconsboost-jsonjsoncppglazereflectcpp
Example using
nlohmann-json:#include "jwt-cpp/traits/nlohmann-json/traits.h" int main() { using traits = jwt::traits::nlohmann_json; // Use 'traits' in jwt::create<traits>(), jwt::decode<traits>(), etc. }#include "jwt-cpp/traits/nlohmann-json/traits.h" int main() { using traits = jwt::traits::nlohmann_json; const auto time = jwt::date::clock::now(); const auto token = jwt::create<traits>() .set_type("JWT") .set_issuer("auth.mydomain.io") .set_audience("mydomain.io") .set_issued_at(time) .set_not_before(time) .set_expires_at(time + std::chrono::minutes{2} + std::chrono::seconds{15}) .sign(jwt::algorithm::none{}); const auto decoded = jwt::decode<traits>(token); jwt::verify<traits>() .allow_algorithm(jwt::algorithm::none{}) .with_issuer("auth.mydomain.io") .with_audience("mydomain.io") .verify(decoded); }