{"id":15047549,"url":"https://github.com/arun11299/cpp-jwt","last_synced_at":"2025-10-18T16:08:44.739Z","repository":{"id":27899700,"uuid":"107301158","full_name":"arun11299/cpp-jwt","owner":"arun11299","description":"JSON Web Token library for C++","archived":false,"fork":false,"pushed_at":"2024-02-11T03:03:40.000Z","size":5856,"stargazers_count":406,"open_issues_count":18,"forks_count":115,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-03-28T17:07:03.425Z","etag":null,"topics":["cpp11","cpp14","cpp17","jwt","jwt-header","security"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arun11299.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-10-17T17:22:06.000Z","updated_at":"2025-03-19T15:57:08.000Z","dependencies_parsed_at":"2024-02-11T04:19:24.673Z","dependency_job_id":"866a3c3b-43d7-4170-baac-fcb23d275c50","html_url":"https://github.com/arun11299/cpp-jwt","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arun11299%2Fcpp-jwt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arun11299%2Fcpp-jwt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arun11299%2Fcpp-jwt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arun11299%2Fcpp-jwt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arun11299","download_url":"https://codeload.github.com/arun11299/cpp-jwt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247226213,"owners_count":20904465,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp11","cpp14","cpp17","jwt","jwt-header","security"],"created_at":"2024-09-24T21:00:03.590Z","updated_at":"2025-10-18T16:08:44.629Z","avatar_url":"https://github.com/arun11299.png","language":"C++","readme":"\u003ch1 align=\"center\"\u003eCPP-JWT\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003cstrong\u003eA C++14 library for JSON Web Tokens(JWT)\u003c/strong\u003e\n\u003c/div\u003e\n\n\u003cbr/\u003e\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"http://jwt.io/img/logo-asset.svg\" /\u003e\n\u003c/div\u003e\n\n\u003cbr/\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003csub\u003e\n    A little library built with lots of ❤︎  for working with JWT easier.\n    By Arun Muralidharan.\n  \u003c/sub\u003e\n\u003c/div\u003e\n\n## Table of Contents\n- [What is it](#what-is-it)\n- [Example](#example)\n- [API Philosophy](#api-philosophy)\n- [Support](#support)\n- [External Dependencies](#external-dependencies)\n- [Thanks to...](#thanks-to...)\n- [Compiler Support](#compiler-support)\n- [Installation](#installation)\n- [Parameters](#parameters)\n- [Claim Data Types](#claim-data-types)\n- [Advanced Examples](#advanced-examples)\n- [Error Codes \u0026 Exceptions](#error-codes-\u0026-exceptions)\n- [Additional Header Data](#additional-header-data)\n- [Things for improvement](#things-for-improvement)\n- [LICENSE](#license)\n\n\n## What is it ?\nFor the uninitiated, JSON Web Token(JWT) is a JSON based standard (\u003ca href=\"https://tools.ietf.org/html/rfc7519\"\u003eRFC-7519\u003c/a\u003e) for creating assertions or access tokens that consists of some claims (encoded within the assertion).\nThis 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.\n\nFew good resources on this material which I found useful are:\n  \u003ca href=\"https://scotch.io/tutorials/the-anatomy-of-a-json-web-token\"\u003eAnatomy of JWT\u003c/a\u003e\n  \u003ca href=\"https://auth0.com/learn/json-web-tokens/\"\u003eLearn JWT\u003c/a\u003e\n  \u003ca href=\"https://tools.ietf.org/html/rfc7519\"\u003eRFC 7519\u003c/a\u003e\n\n\n## Example\n  Lets dive into see a simple example of encoding and decoding in Python. Taking the example of \u003cstrong\u003epyjwt\u003c/strong\u003e module from its docs.\n\n  ```python\n  \u003e\u003eimport jwt\n  \u003e\u003ekey = 'secret'\n  \u003e\u003e\n  \u003e\u003eencoded = jwt.encode({'some': 'payload'}, key, algorithm='HS256')\n  'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5NiznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZg'\n  \u003e\u003e\n  \u003e\u003edecoded = jwt.decode(encoded, key, algorithms='HS256')\n  {'some': 'payload'}\n  ```\n\n  Now, lets look at our C++ code doing the same thing.\n  ```cpp\n  #include \u003ciostream\u003e\n  #include \"jwt/jwt.hpp\"\n\n  int main() {\n    using namespace jwt::params;\n\n    auto key = \"secret\"; //Secret to use for the algorithm\n    //Create JWT object\n    jwt::jwt_object obj{algorithm(\"HS256\"), payload({{\"some\", \"payload\"}}), secret(key)};\n\n    //Get the encoded string/assertion\n    auto enc_str = obj.signature();\n    std::cout \u003c\u003c enc_str \u003c\u003c std::endl;\n\n    //Decode\n    auto dec_obj = jwt::decode(enc_str, algorithms({\"HS256\"}), secret(key));\n    std::cout \u003c\u003c dec_obj.header() \u003c\u003c std::endl;\n    std::cout \u003c\u003c dec_obj.payload() \u003c\u003c std::endl;\n\n    return 0;\n  }\n  ```\n\n  It outputs:\n  ```\n  eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5NiznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZg\n  {\"alg\":\"HS256\",\"typ\":\"JWT\"}\n  {\"some\":\"payload\"}\n  ```\n\n  Almost the same API, except for some ugliness here and there. But close enough!\n\n  Lets take another example in which we will see to add payload claim having type other than string.\n  The \u003ccode\u003epayload\u003c/code\u003e function used in the above example to create \u003ccode\u003ejwt_object\u003c/code\u003e object can only take strings. For anything else, it will throw a compilation error.\n\n  For adding claims having values other than string, \u003ccode\u003ejwt_object\u003c/code\u003e class provides \u003ccode\u003eadd_claim\u003c/code\u003e API. We will also see few other APIs in the next example. Make sure to read the comments :).\n\n  ```cpp\n    #include \u003cchrono\u003e\n    #include \u003ccassert\u003e\n    #include \u003ciostream\u003e\n    #include \"jwt/jwt.hpp\"\n\n    int main() {\n      using namespace jwt::params;\n\n      jwt::jwt_object obj{algorithm(\"HS256\"), secret(\"secret\"), payload({{\"user\", \"admin\"}})};\n\n      //Use add_claim API to add claim values which are\n      // _not_ strings.\n      // For eg: `iat` and `exp` claims below.\n      // Other claims could have been added in the payload\n      // function above as they are just stringy things.\n      obj.add_claim(\"iss\", \"arun.muralidharan\")\n         .add_claim(\"sub\", \"test\")\n         .add_claim(\"id\", \"a-b-c-d-e-f-1-2-3\")\n         .add_claim(\"iat\", 1513862371)\n         .add_claim(\"exp\", std::chrono::system_clock::now() + std::chrono::seconds{10})\n         ;\n\n      //Use `has_claim` to check if the claim exists or not\n      assert (obj.has_claim(\"iss\"));\n      assert (obj.has_claim(\"exp\"));\n\n      //Use `has_claim_with_value` to check if the claim exists\n      //with a specific value or not.\n      assert (obj.payload().has_claim_with_value(\"id\", \"a-b-c-d-e-f-1-2-3\"));\n      assert (obj.payload().has_claim_with_value(\"iat\", 1513862371));\n\n      //Remove a claim using `remove_claim` API.\n      //Most APIs have an overload which takes enum class type as well\n      //It can be used interchangeably with strings.\n      obj.remove_claim(jwt::registered_claims::expiration);\n      assert (!obj.has_claim(\"exp\"));\n\n      //Using `add_claim` with extra features.\n      //Check return status and overwrite\n      bool ret = obj.payload().add_claim(\"sub\", \"new test\", false/*overwrite*/);\n      assert (!ret);\n\n      // Overwrite an existing claim\n      ret = obj.payload().add_claim(\"sub\", \"new test\", true/*overwrite*/);\n      assert (ret);\n\n      assert (obj.payload().has_claim_with_value(\"sub\", \"new test\"));\n\n      return 0;\n    }\n  ```\n\nThe \u003ccode\u003ejwt_object\u003c/code\u003e class is basically a composition of the JWT component classes, which are \u003ccode\u003ejwt_header\u003c/code\u003e \u0026 \u003ccode\u003ejwt_payload\u003c/code\u003e. For convenience \u003ccode\u003ejwt_object\u003c/code\u003e exposes only few important APIs to the user, the remaining APIs under \u003ccode\u003ejwt_header\u003c/code\u003e and \u003ccode\u003ejwt_payload\u003c/code\u003e can be accessed by calling \u003ccode\u003ejwt_object::header()\u003c/code\u003e and \u003ccode\u003ejwt_object::payload()\u003c/code\u003e APIs.\n\n\n## API Philosophy\nI wanted to make the code easy to read and at the same time make most of the standard library and the modern features.\nIt also uses some metaprogramming tricks to enforce type checks and give better error messages.\n\nThe design of `parameters` alleviates the pain of remembering positional arguments. Also makes the APIs more extensible for future enhancements.\n\nThe library has 2 sets of APIs for encoding and decoding:\n  - API which takes an instance of \u003ccode\u003estd::error_code\u003c/code\u003e\n    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.\n  - API which throws exceptions\n    All the errors would be thrown as exception.\n\n## Support\n\u003cstrong\u003eAlgorithms and features supported\u003c/strong\u003e\n- [x] HS256\n- [x] HS384\n- [x] HS512\n- [x] RS256\n- [x] RS384\n- [x] RS512\n- [x] ES256\n- [x] ES384\n- [x] ES512\n- [x] Sign\n- [x] Verify\n- [x] iss (issuer) check\n- [x] sub (subject) check\n- [x] aud (audience) check\n- [x] exp (expiration time) check\n- [x] nbf (not before time) check\n- [x] iat (issued at) check\n- [x] jti (JWT id) check\n- [x] JWS header addition support. For eg \"kid\" support.\n\n## External Dependencies\n  - \u003cstrong\u003eOpenSSL \u003c/strong\u003e(Version \u003e= 1.0.2j)\n    Might work with older version as well, but I did not check that.\n  - \u003cstrong\u003eGoogle Test Framework\u003c/strong\u003e\n    For running the tests\n  - \u003cstrong\u003enlohmann JSON library\u003c/strong\u003e\n    The awesome JSON library :)\n\n## Thanks to...\n    - \u003ca href=\"https://github.com/benmcollins/libjwt\"\u003eben-collins JWT library\u003c/a\u003e\n    - Howard Hinnant for the stack allocator\n    - libstd++ code (I took the hashing code for string_view)\n\n## Compiler Support\n\nTested with \u003cstrong\u003eclang-5.0\u003c/strong\u003e and \u003cstrong\u003eg++-6.4\u003c/strong\u003e.\nWith issue#12, \u003cstrong\u003eVS2017\u003c/strong\u003e is also supported.\n\n## Building the library\n\n### using conan\n\n```shell\nmkdir build\ncd build\nconan install .. --build missing\ncmake ..\ncmake --build . -j\n```\n\n### using debian\n\n```shell\nsudo apt install nlohmann-json3-dev \nsudo apt install libgtest-dev\nsudo apt install libssl-dev\nmkdir build\ncd build\ncmake ..\ncmake --build . -j\n```\n\n## Consuming the library\n\nThis library is uses cmake as a build system.\n```cmake\n# you can use cmake's `find_package` after installation or `add_subdirectory` when vendoring this repository\n\nfind_package(cpp-jwt REQUIRED)\n# or\nadd_subdirectory(third_party/cpp-jwt)\n\nadd_executable(main main.cpp)\ntarget_link_libraries(main cpp-jwt::cpp-jwt)\n```\n\nYou can also use this library as a conan package, its available in the [conan center](https://conan.io/center/cpp-jwt):\njust add `cpp-jwt[\u003e=1.2]` to your conanfile.txt.\n\nIt can also be installed using [vcpkg](https://github.com/microsoft/vcpkg) by adding `\"cpp-jwt\"` to the dependencies in your `vcpkg.json` file.\n\n## Parameters\nThere are two sets of parameters which can be used for creating `jwt_object` and for decoding.\nAll the parameters are basically a function which returns an instance of a type which are modelled after \u003ccode\u003eParameterConcept\u003c/code\u003e (see \u003ccode\u003ejwt::detail::meta::is_parameter_concept\u003c/code\u003e).\n\n\n- \u003cstrong\u003e\u003ccode\u003ejwt_object\u003c/code\u003e creation parameters\u003c/strong\u003e\n  - \u003cstrong\u003epayload\u003c/strong\u003e\n\n    Used to populate the claims while creating the `jwt_object` instance.\n\n    There are two overloads of this function:\n    - Takes Initializer list of \u003ccode\u003epair\u003cstring_view, string_view\u003e\u003c/code\u003e\n\n      Easy to pass claims with string values which are all known at the time of object creation.\n      Can be used like:\n      ```cpp\n      jwt_object obj {\n        payload({\n            {\"iss\", \"some-guy\"},\n            {\"sub\", \"something\"},\n            {\"X-pld\", \"data1\"}\n          }),\n          ... // Add other parameters\n      };\n      ```\n      Claim values which are not strings/string_views cannot be used.\n\n    - Takes any type which models \u003ccode\u003eMappingConcept\u003c/code\u003e (see \u003ccode\u003edetail::meta::is_mapping_concept\u003c/code\u003e)\n\n      This overload can accept \u003ccode\u003estd::map\u003c/code\u003e or \u003ccode\u003estd::unordered_map\u003c/code\u003e like containers.\n      Can be used like:\n      ```cpp\n      map\u003cstring, string\u003e m;\n      m[\"iss\"] = \"some-guy\";\n      m[\"sub\"] = \"something\";\n      m[\"X-pld\"] = \"data1\";\n\n      jwt_object obj{\n        payload(std::move(m)),\n        ... // Add other parameters\n      };\n      //OR\n      jwt_object obj{\n        payload(m),\n        ... // Add other parameters\n      };\n      ```\n\n  - \u003cstrong\u003esecret\u003c/strong\u003e\n\n    Used to pass the key which could be some random string or the bytes of the PEM encoded public key\n    file in PEM format (wrapped in -----BEGIN PUBLIC KEY----- block) as string.\n    The passed string type must be convertible to \u003ccode\u003ejwt::string_view\u003c/code\u003e\n\n  - \u003cstrong\u003ealgorithm\u003c/strong\u003e\n\n    Used to pass the type of algorithm to use for encoding.\n    There are two overloads of this function:\n    - Takes \u003ccode\u003ejwt::string_view\u003c/code\u003e\n\n      Can pass the algorithm value in any case. It is case agnostic.\n\n    - Takes value of type \u003ccode\u003eenum class jwt::algorithm\u003c/code\u003e\n\n  - \u003cstrong\u003eheaders\u003c/strong\u003e\n\n    Used to populate fields in JWT header. It is very similar to `payload` function parameter.\n    There are two overloads for this function which are similar to how \u003ccode\u003epayload\u003c/code\u003e function is.\n    This parameter can be used to add headers other that \u003cstrong\u003ealg\u003c/strong\u003e and \u003cstrong\u003etyp\u003c/strong\u003e.\n\n    Same as the case with payload, only string values can be used with this. For adding values of other\n    data types, use \u003ccode\u003eadd_header\u003c/code\u003e API of \u003ccode\u003ejwt_header\u003c/code\u003e class.\n\n    For example adding `kid` header with other additional data fields.\n    ```cpp\n    jwt_object obj{\n      algorithm(\"HS256\"),\n      headers({\n        {\"kid\", \"12-34-56\"},\n        {\"xtra\", \"header\"}\n      })\n      ... // Add other parameters\n    };\n    ```\n\n\n- \u003cstrong\u003eDecoding parameters\u003c/strong\u003e\n\n  - \u003cstrong\u003ealgorithms\u003c/strong\u003e\n\n    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 \u003ccode\u003eInvalidAlgorithmError\u003c/code\u003e exception or \u003ccode\u003eInvalidAlgorithm\u003c/code\u003e error would be set based upon the API being used.\n\n    There are two overloads for this function:\n    - Takes initializer-list of string values\n    - Takes in any type which satifies the \u003cstrong\u003eSequenceConcept\u003c/strong\u003e (see \u003ccode\u003eidetail::meta::is_sequence_concept\u003c/code\u003e)\n\n  ```cpp\n  jwt::decode(algorithms({\"none\", \"HS256\", \"RS256\"}), ...);\n\n  OR\n\n  std::vector\u003cstd::string\u003e algs{\"none\", \"HS256\", \"RS256\"};\n  jwt::decode(algorithms(algs), ...);\n  ```\n\n  - \u003cstrong\u003esecret\u003c/strong\u003e\n\n    Optional parameter. To be supplied only when the algorithm used is not \"none\". Else would throw/set \u003ccode\u003eKeyNotPresentError\u003c/code\u003e / \u003ccode\u003eKeyNotPresent\u003c/code\u003e exception/error.\n\n  - \u003cstrong\u003eleeway\u003c/strong\u003e\n\n    Optional parameter. Used with validation of \"Expiration\" and \"Not Before\" claims.\n    The value passed should be `seconds` to account for clock skew.\n    Default value is `0` seconds.\n\n  - \u003cstrong\u003everify\u003c/strong\u003e\n\n    Optional parameter. Suggests if verification of claims should be done or not.\n    Takes a boolean value.\n    By default verification is turned on.\n\n  - \u003cstrong\u003eissuer\u003c/strong\u003e\n\n    Optional parameter.\n    Takes a string value.\n    Validates the passed issuer value against the one present in the decoded JWT object. If the values do not match \u003ccode\u003eInvalidIssuerError\u003c/code\u003e or \u003ccode\u003eInvalidIssuer\u003c/code\u003e exception or error_code is thrown/set.\n\n  - \u003cstrong\u003eaud\u003c/strong\u003e\n\n    Optional parameter.\n    Takes a string value.\n    Validates the passed audience value against the one present in the decoded JWT object. If the values do not match \u003ccode\u003eInvalidAudienceError\u003c/code\u003e or \u003ccode\u003eInvalidAudience\u003c/code\u003e exception or error_code is thrown/set.\n\n  - \u003cstrong\u003esub\u003c/strong\u003e\n\n    Optional parameter.\n    Takes a string value.\n    Validates the passed subject value against the one present in the decoded JWT object. If the values do not match \u003ccode\u003eInvalidSubjectError\u003c/code\u003e or \u003ccode\u003eInvalidSubject\u003c/code\u003e exception or error_code is thrown/set.\n\n  - \u003cstrong\u003evalidate_iat\u003c/strong\u003e\n\n    Optional parameter.\n    Takes a boolean value.\n    Validates the IAT claim. Only checks whether the field is present and is of correct type. If not throws/sets \u003ccode\u003eInvalidIATError\u003c/code\u003e or \u003ccode\u003eInvalidIAT\u003c/code\u003e.\n\n    Default value is false.\n\n  - \u003cstrong\u003evalidate_jti\u003c/strong\u003e\n\n    Optional parameter.\n    Takes a boolean value.\n    Validates the JTI claim. Only checks for the presence of the claim. If  not throws or sets \u003ccode\u003eInvalidJTIError\u003c/code\u003e or \u003ccode\u003eInvalidJTI\u003c/code\u003e.\n\n    Default is false.\n\n\n## Claim Data Types\nFor the registered claim types the library assumes specific data types for the claim values. Using anything else is not supported and would result in runtime JSON parse error.\n\n    Claim                 |  Data Type\n    -----------------------------------\n    Expiration(exp)       |  uint64_t (Epoch time in seconds)\n    -----------------------------------\n    Not Before(nbf)       |  uint64_t (Epoch time in seconds)\n    -----------------------------------\n    Issuer(iss)           |  string\n    -----------------------------------\n    Audience(aud)         |  string\n    -----------------------------------\n    Issued At(iat)        |  uint64_t (Epoch time in seconds)\n    -----------------------------------\n    Subject(sub)          |  string\n    -----------------------------------\n    JTI(jti)              | \u003cValue type not checked by library. Upto application.\u003e\n    -----------------------------------\n\n\n## Advanced Examples\nWe will see few complete examples which makes use of error code checks and exception handling.\nThe examples are taken from the \"tests\" section. Users are requested to checkout the tests to find out more ways to use this library.\n\nExpiration verification example (uses error_code):\n```cpp\n#include \u003ccassert\u003e\n#include \u003ciostream\u003e\n#include \"jwt/jwt.hpp\"\n\nint main() {\n  using namespace jwt::params;\n\n  jwt::jwt_object obj{algorithm(\"HS256\"), secret(\"secret\")};\n  obj.add_claim(\"iss\", \"arun.muralidharan\")\n     .add_claim(\"exp\", std::chrono::system_clock::now() - std::chrono::seconds{1})\n     ;\n\n  std::error_code ec;\n  auto enc_str = obj.signature(ec);\n  assert (!ec);\n\n  auto dec_obj = jwt::decode(enc_str, algorithms({\"HS256\"}), ec, secret(\"secret\"), verify(true));\n  assert (ec);\n  assert (ec.value() == static_cast\u003cint\u003e(jwt::VerificationErrc::TokenExpired));\n\n  return 0;\n}\n```\n\nExpiration verification example (uses exception):\n```cpp\n#include \u003ccassert\u003e\n#include \u003ciostream\u003e\n#include \"jwt/jwt.hpp\"\n\nint main() {\n  using namespace jwt::params;\n\n  jwt::jwt_object obj{algorithm(\"HS256\"), secret(\"secret\")};\n\n  obj.add_claim(\"iss\", \"arun.muralidharan\")\n     .add_claim(\"exp\", std::chrono::system_clock::now() - std::chrono::seconds{1})\n     ;\n\n  auto enc_str = obj.signature();\n\n  try {\n    auto dec_obj = jwt::decode(enc_str, algorithms({\"HS256\"}), secret(\"secret\"), verify(true));\n  } catch (const jwt::TokenExpiredError\u0026 e) {\n    //Handle Token expired exception here\n    //...\n  } catch (const jwt::SignatureFormatError\u0026 e) {\n    //Handle invalid signature format error\n    //...\n  } catch (const jwt::DecodeError\u0026 e) {\n    //Handle all kinds of other decode errors\n    //...\n  } catch (const jwt::VerificationError\u0026 e) {\n    // Handle the base verification error.\n    //NOTE: There are other derived types of verification errors\n    // which will be discussed in next topic.\n  } catch (...) {\n    std::cerr \u003c\u003c \"Caught unknown exception\\n\";\n  }\n\n  return 0;\n}\n```\n\nInvalid issuer test(uses error_code):\n```cpp\n#include \u003ccassert\u003e\n#include \u003ciostream\u003e\n#include \"jwt/jwt.hpp\"\n\nint main() {\n  using namespace jwt::params;\n\n  jwt::jwt_object obj{algorithm(\"HS256\"), secret(\"secret\"), payload({{\"sub\", \"test\"}})};\n\n  std::error_code ec;\n  auto enc_str = obj.signature(ec);\n  assert (!ec);\n\n  auto dec_obj = jwt::decode(enc_str, algorithms({\"HS256\"}), ec, secret(\"secret\"), issuer(\"arun.muralidharan\"));\n  assert (ec);\n\n  assert (ec.value() == static_cast\u003cint\u003e(jwt::VerificationErrc::InvalidIssuer));\n\n  return 0;\n}\n```\n\n## Error Codes \u0026 Exceptions\nThe library as we saw earlier supports error reporting via both exceptions and error_code.\n\n\u003cstrong\u003eError codes:\u003c/strong\u003e\n\nThe error codes are divided into different categories:\n- Algorithm Errors\n\n  Used for reporting errors at the time of encoding / signature creation.\n  ```cpp\n  enum class AlgorithmErrc\n  {\n    SigningErr = 1,\n    VerificationErr,\n    KeyNotFoundErr,\n    NoneAlgorithmUsed, // Not an actual error!\n  };\n  ```\n\n  \u003cstrong\u003eNOTE:\u003c/strong\u003e \u003ccode\u003eNoneAlgorithmUsed\u003c/code\u003e will be set in the error_code, but it usually should not be treated as a hard error when NONE algorithm is used intentionally.\n\n- Decode Errors\n\n  Used for reporting errors at the time of decoding. Different categories of decode errors are:\n  ```cpp\n  enum class DecodeErrc\n  {\n    // No algorithms provided in decode API\n    EmptyAlgoList = 1,\n    // The JWT signature has incorrect format\n    SignatureFormatError,\n    // The JSON library failed to parse\n    JsonParseError,\n    // Algorithm field in header is missing\n    AlgHeaderMiss,\n    // Type field in header is missing\n    TypHeaderMiss,\n    // Unexpected type field value\n    TypMismatch,\n    // Found duplicate claims\n    DuplClaims,\n    // Key/Secret not passed as decode argument\n    KeyNotPresent,\n    // Key/secret passed as argument for NONE algorithm.\n    // Not a hard error.\n    KeyNotRequiredForNoneAlg,\n  };\n  ```\n\n- Verification errors\n\n  Used for reporting verification errors when the verification falg is set to true in decode API.\n  Different categories of decode errors are:\n  ```cpp\n  enum class VerificationErrc\n  {\n    //Algorithms provided does not match with header\n    InvalidAlgorithm = 1,\n    //Token is expired at the time of decoding\n    TokenExpired,\n    //The issuer specified does not match with payload\n    InvalidIssuer,\n    //The subject specified does not match with payload\n    InvalidSubject,\n    //The field IAT is not present or is of invalid type\n    InvalidIAT,\n    //Checks for the existence of JTI\n    //if validate_jti is passed in decode\n    InvalidJTI,\n    //The audience specified dowes not match with payload\n    InvalidAudience,\n    //Decoded before nbf time\n    ImmatureSignature,\n    //Signature match error\n    InvalidSignature,\n    // Invalid value type used for known claims\n    TypeConversionError,\n  };\n  ```\n\n\u003cstrong\u003eExceptions:\u003c/strong\u003e\nThere are exception types created for almost all the error codes above.\n\n- MemoryAllocationException\n\n  Derived from \u003ccode\u003estd::bad_alloc\u003c/code\u003e. Thrown for memory allocation errors in OpenSSL C API.\n\n- SigningError\n\n  Derived from \u003ccode\u003estd::runtime_error\u003c/code\u003e. Thrown for failures in OpenSSL APIs while signing.\n\n- DecodeError\n\n  Derived from \u003ccode\u003estd::runtime_error\u003c/code\u003e. Base class for all decoding related exceptions.\n\n  - SignatureFormatError\n\n    Thrown if the format of the signature is not as expected.\n\n  - KeyNotPresentError\n\n    Thrown if key/secret is not passed in with the decode API if the algorithm used is something other than \"none\".\n\n- VerificationError\n\n  Derived from \u003ccode\u003estd::runtime_error\u003c/code\u003e. Base class exception for all kinds of verification errors. Verification errors are thrown only when the verify decode parameter is set to true.\n\n  - InvalidAlgorithmError\n  - TokenExpiredError\n  - InvalidIssuerError\n  - InvalidAudienceError\n  - InvalidSubjectError\n  - InvalidIATError\n  - InvalidJTIError\n  - ImmatureSignatureError\n  - InvalidSignatureError\n  - TypeConversionError\n\n  NOTE: See the error code section for explanation on above verification errors or checkout \u003ccode\u003eexceptions.hpp\u003c/code\u003e header for more details.\n\n\n## Additional Header Data\nGenerally the header consists only of `type` and `algorithm` fields. But there could be a need to add additional header fields. For example, to provide some kind of hint about what algorithm was used to sign the JWT. Checkout JOSE header section in \u003ca href=\"https://tools.ietf.org/html/rfc7515\"\u003eRFC-7515\u003c/a\u003e.\n\nThe library provides APIs to do that as well.\n\n```cpp\n#include \u003ccassert\u003e\n#include \u003ciostream\u003e\n#include \"jwt/jwt.hpp\"\n\nint main() {\n  using namespace jwt::params;\n\n  jwt::jwt_object obj{\n      headers({\n        {\"alg\", \"none\"},\n        {\"typ\", \"jwt\"},\n        }),\n      payload({\n        {\"iss\", \"arun.muralidharan\"},\n        {\"sub\", \"nsfw\"},\n        {\"x-pld\", \"not my ex\"}\n      })\n  };\n\n  bool ret = obj.header().add_header(\"kid\", 1234567);\n  assert (ret);\n\n  ret = obj.header().add_header(\"crit\", std::array\u003cstd::string, 1\u003e{\"exp\"});\n  assert (ret);\n\n  std::error_code ec;\n  auto enc_str = obj.signature();\n\n  auto dec_obj = jwt::decode(enc_str, algorithms({\"none\"}), ec, verify(false));\n\n  // Should not be a hard error in general\n  assert (ec.value() == static_cast\u003cint\u003e(jwt::AlgorithmErrc::NoneAlgorithmUsed));\n}\n```\n\n\n## Things for improvement\nMany things!\nEncoding and decoding JWT is fairly a simple task and could be done in a single source file. I have tried my best to get the APIs and design correct in how much ever time I could give for this project. Still, there are quite a few places (or all the places :( ? ) where things are not correct or may not be the best approach.\n\nWith C++, it is pretty easy to go overboard and create something very difficult or something very straightforward (not worth to be a library). My intention was to make a sane library easier for end users to use while also making the life of someone reading the source have fairly good time debugging some issue.\n\nThings one may have questions about\n- There is a string_view implementation. Why not use \u003ccode\u003eboost::string_ref\u003c/code\u003e ?\n\n  Sorry, I love boost! But, do not want it to be part of dependency.\n  If you use C++17 or greater `std::string_view` gets used instead and `jwt::string_view` implementation does not get included.\n\n- You are not using the stack allocator or the shart string anywhere. Why to include it then ?\n\n  I will be using it in few places where I am sure I need not use `std::string` especially in the signing code.\n\n- Why the complete `nlohmann JSON` is part of your library ?\n\n  Honestly did not know any better way. I know there are ways to use third party github repositories, but I do not know how to do that. Once I figure that out, I may move it out.\n\n- Am I bound to use `nlohmann JSON` ? Can I use some other JSON library ?\n\n  As of now, ys. You cannot use any other JSON library unless you change the code. I would have liked to provide some adaptors for JSON interface. Perhaps in future, if required.\n\n- Error codes and exceptions....heh?\n\n  Yeah, I often wonder if that was the right approach. I could have just stuck with error codes and be happy. But that was a good learning time for me.\n\n- Where to find more about the usage ?\n\n  Checkout the tests. It has examples for all the algorithms which are supported.\n\n- Support for C++11 seems trivial based on the changes required. Why not support C+11 then ?\n\n  Its 2018 now! If I ever start getting requests to have support for C++11, then I will surely consider it.\n\n- The Metaprogramming concept checks for Sequence and Mapping looks sad.\n\n  Yeah I know. Just hacked something very basic.\n\n\n## License\n\nMIT License\n\nCopyright (c) 2017 Arun Muralidharan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","funding_links":[],"categories":["Miscellaneous","Recently Updated","C++"],"sub_categories":["[Who Wants to Be a Millionare](https://www.boardgamecapital.com/who-wants-to-be-a-millionaire-rules.htm)"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farun11299%2Fcpp-jwt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farun11299%2Fcpp-jwt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farun11299%2Fcpp-jwt/lists"}