MCPcopy Create free account
hub / github.com/arun11299/cpp-jwt

github.com/arun11299/cpp-jwt @v1.5.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.5.1 ↗ · + Follow
821 symbols 1,977 edges 35 files 359 documented · 44% updated 4mo agov1.5.1 · 2025-08-30★ 43918 open issues

Browse by type

Functions 600 Types & classes 221
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

CPP-JWT

A C++14 library for JSON Web Tokens(JWT)

A little library built with lots of ❤︎ for working with JWT easier. By Arun Muralidharan.

Table of Contents

What is it ?

For the uninitiated, JSON Web Token(JWT) is a JSON based standard (RFC-7519) for creating assertions or access tokens that consists of some claims (encoded within the assertion). This assertion can be used in some kind of bearer authentication mechanism that the server will provide to clients, and the clients can make use of the provided assertion for accessing resources.

Few good resources on this material which I found useful are: Anatomy of JWT Learn JWT RFC 7519

Example

Lets dive into see a simple example of encoding and decoding in Python. Taking the example of pyjwt module from its docs.

```python

import jwt key = 'secret'

encoded = jwt.encode({'some': 'payload'}, key, algorithm='HS256') 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5NiznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZg'

decoded = jwt.decode(encoded, key, algorithms='HS256') {'some': 'payload'} ```

Now, lets look at our C++ code doing the same thing. ```cpp #include #include "jwt/jwt.hpp"

int main() { using namespace jwt::params;

auto key = "secret"; //Secret to use for the algorithm
//Create JWT object
jwt::jwt_object obj{algorithm("HS256"), payload({{"some", "payload"}}), secret(key)};

//Get the encoded string/assertion
auto enc_str = obj.signature();
std::cout << enc_str << std::endl;

//Decode
auto dec_obj = jwt::decode(enc_str, algorithms({"HS256"}), secret(key));
std::cout << dec_obj.header() << std::endl;
std::cout << dec_obj.payload() << std::endl;

return 0;

} ```

It outputs: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5NiznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZg {"alg":"HS256","typ":"JWT"} {"some":"payload"}

Almost the same API, except for some ugliness here and there. But close enough!

Lets take another example in which we will see to add payload claim having type other than string. The payload function used in the above example to create jwt_object object can only take strings. For anything else, it will throw a compilation error.

For adding claims having values other than string, jwt_object class provides add_claim API. We will also see few other APIs in the next example. Make sure to read the comments :).

```cpp #include #include #include #include "jwt/jwt.hpp"

int main() {
  using namespace jwt::params;

  jwt::jwt_object obj{algorithm("HS256"), secret("secret"), payload({{"user", "admin"}})};

  //Use add_claim API to add claim values which are
  // _not_ strings.
  // For eg: `iat` and `exp` claims below.
  // Other claims could have been added in the payload
  // function above as they are just stringy things.
  obj.add_claim("iss", "arun.muralidharan")
     .add_claim("sub", "test")
     .add_claim("id", "a-b-c-d-e-f-1-2-3")
     .add_claim("iat", 1513862371)
     .add_claim("exp", std::chrono::system_clock::now() + std::chrono::seconds{10})
     ;

  //Use `has_claim` to check if the claim exists or not
  assert (obj.has_claim("iss"));
  assert (obj.has_claim("exp"));

  //Use `has_claim_with_value` to check if the claim exists
  //with a specific value or not.
  assert (obj.payload().has_claim_with_value("id", "a-b-c-d-e-f-1-2-3"));
  assert (obj.payload().has_claim_with_value("iat", 1513862371));

  //Remove a claim using `remove_claim` API.
  //Most APIs have an overload which takes enum class type as well
  //It can be used interchangeably with strings.
  obj.remove_claim(jwt::registered_claims::expiration);
  assert (!obj.has_claim("exp"));

  //Using `add_claim` with extra features.
  //Check return status and overwrite
  bool ret = obj.payload().add_claim("sub", "new test", false/*overwrite*/);
  assert (!ret);

  // Overwrite an existing claim
  ret = obj.payload().add_claim("sub", "new test", true/*overwrite*/);
  assert (ret);

  assert (obj.payload().has_claim_with_value("sub", "new test"));

  return 0;
}

```

The jwt_object class is basically a composition of the JWT component classes, which are jwt_header & jwt_payload. For convenience jwt_object exposes only few important APIs to the user, the remaining APIs under jwt_header and jwt_payload can be accessed by calling jwt_object::header() and jwt_object::payload() APIs.

API Philosophy

I wanted to make the code easy to read and at the same time make most of the standard library and the modern features. It also uses some metaprogramming tricks to enforce type checks and give better error messages.

The design of parameters alleviates the pain of remembering positional arguments. Also makes the APIs more extensible for future enhancements.

The library has 2 sets of APIs for encoding and decoding: - API which takes an instance of std::error_code These APIs will report the errors by setting the error_code. This does not mean that these API would not throw. Memory allocation errors would still be thrown instead of setting the error_code. - API which throws exceptions All the errors would be thrown as exception.

Support

Algorithms and features supported - [x] HS256 - [x] HS384 - [x] HS512 - [x] RS256 - [x] RS384 - [x] RS512 - [x] ES256 - [x] ES384 - [x] ES512 - [x] Sign - [x] Verify - [x] iss (issuer) check - [x] sub (subject) check - [x] aud (audience) check - [x] exp (expiration time) check - [x] nbf (not before time) check - [x] iat (issued at) check - [x] jti (JWT id) check - [x] JWS header addition support. For eg "kid" support.

External Dependencies

  • OpenSSL (Version >= 1.0.2j) Might work with older version as well, but I did not check that.
  • Google Test Framework For running the tests
  • nlohmann JSON library The awesome JSON library :)

Thanks to...

- <a href="https://github.com/benmcollins/libjwt">ben-collins JWT library</a>
- Howard Hinnant for the stack allocator
- libstd++ code (I took the hashing code for string_view)

Compiler Support

Tested with clang-5.0 and g++-6.4. With issue#12, VS2017 is also supported.

Building the library

using conan

mkdir build
cd build
conan install .. --build missing
cmake ..
cmake --build . -j

using debian

sudo apt install nlohmann-json3-dev 
sudo apt install libgtest-dev
sudo apt install libssl-dev
mkdir build
cd build
cmake ..
cmake --build . -j

Consuming the library

This library is uses cmake as a build system.

# you can use cmake's `find_package` after installation or `add_subdirectory` when vendoring this repository

find_package(cpp-jwt REQUIRED)
# or
add_subdirectory(third_party/cpp-jwt)

add_executable(main main.cpp)
target_link_libraries(main cpp-jwt::cpp-jwt)

You can also use this library as a conan package, its available in the conan center: just add cpp-jwt[>=1.2] to your conanfile.txt.

It can also be installed using vcpkg by adding "cpp-jwt" to the dependencies in your vcpkg.json file.

Parameters

There are two sets of parameters which can be used for creating jwt_object and for decoding. All the parameters are basically a function which returns an instance of a type which are modelled after ParameterConcept (see jwt::detail::meta::is_parameter_concept).

  • jwt_object creation parameters
  • payload

    Used to populate the claims while creating the jwt_object instance.

    There are two overloads of this function: - Takes Initializer list of pair

    Easy to pass claims with string values which are all known at the time of object creation. Can be used like: cpp jwt_object obj { payload({ {"iss", "some-guy"}, {"sub", "something"}, {"X-pld", "data1"} }), ... // Add other parameters }; Claim values which are not strings/string_views cannot be used.

    • Takes any type which models MappingConcept (see detail::meta::is_mapping_concept)

    This overload can accept std::map or std::unordered_map like containers. Can be used like: ```cpp map m; m["iss"] = "some-guy"; m["sub"] = "something"; m["X-pld"] = "data1";

    jwt_object obj{ payload(std::move(m)), ... // Add other parameters }; //OR jwt_object obj{ payload(m), ... // Add other parameters }; ```

  • secret

    Used to pass the key which could be some random string or the bytes of the PEM encoded public key file in PEM format (wrapped in -----BEGIN PUBLIC KEY----- block) as string. The passed string type must be convertible to jwt::string_view

  • algorithm

    Used to pass the type of algorithm to use for encoding. There are two overloads of this function: - Takes jwt::string_view

    Can pass the algorithm value in any case. It is case agnostic.

    • Takes value of type enum class jwt::algorithm
  • headers

    Used to populate fields in JWT header. It is very similar to payload function parameter. There are two overloads for this function which are similar to how payload function is. This parameter can be used to add headers other that alg and typ.

    Same as the case with payload, only string values can be used with this. For adding values of other data types, use add_header API of jwt_header class.

    For example adding kid header with other additional data fields. cpp jwt_object obj{ algorithm("HS256"), headers({ {"kid", "12-34-56"}, {"xtra", "header"} }) ... // Add other parameters };

  • Decoding parameters

  • algorithms

    This is a mandatory parameter which takes a sequence of algorithms (as string) which the user would like to permit when validating the JWT. The value in the header for "alg" would be matched against the provided sequence of values. If nothing matches InvalidAlgorithmError exception or InvalidAlgorithm error would be set based upon the API being used.

    There are two overloads for this function: - Takes initializer-list of string values - Takes in any type which satifies the SequenceConcept (see idetail::meta::is_sequence_concept)

```cpp jwt::decode(algorithms({"none", "HS256", "RS256"}), ...);

OR

std::vector algs{"none", "HS256", "RS256"}; jwt::decode(algorithms(algs), ...); ```

  • secret

    Optional parameter. To be supplied only when the algorithm used is not "none". Else would throw/set KeyNotPresentError / KeyNotPresent exception/error.

  • leeway

    Optional parameter. Used with validation of "Expiration" and "Not Before" claims. The value passed should be seconds to account for clock skew. Default value is 0 seconds.

  • verify

    Optional parameter. Suggests if verification of claims should be done or not. Takes a boolean value. By default verification is turned on.

  • issuer

    Optional parameter. Takes a string value. Validates the passed issuer value against the one present in the decoded JWT object. If the values do not match InvalidIssuerError or InvalidIssuer exception or error_code is thrown/set.

  • aud

    Optional parameter. Takes a string value. Validates the passed audience value against the one present in the decoded JWT object. If the values do not match InvalidAudienceError or InvalidAudience exception or error_code is thrown/set.

  • sub

    Optional parameter. Takes a string value. Validates the passed subject value against the one present in the decoded JWT object. If the values do not match InvalidSubjectError or InvalidSubject exce

Core symbols most depended-on inside this repo

Shape

Method 397
Class 207
Function 203
Enum 14

Languages

C++100%
C1%

Modules by API surface

include/jwt/json/json.hpp534 symbols
include/jwt/parameters.hpp54 symbols
include/jwt/jwt.hpp39 symbols
include/jwt/algorithm.hpp37 symbols
include/jwt/exceptions.hpp35 symbols
include/jwt/string_view.hpp32 symbols
include/jwt/detail/meta.hpp17 symbols
include/jwt/base64.hpp12 symbols
include/jwt/stack_alloc.hpp10 symbols
include/jwt/test/test_sv.cc7 symbols
include/jwt/error_codes.hpp7 symbols
tests/test_jwt_object.cc3 symbols

For agents

$ claude mcp add cpp-jwt \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page