Skip to content

Commit

Permalink
Documentation Refresh (Thalhammer#323)
Browse files Browse the repository at this point in the history
* Create getting-started.md

* Update getting-started.md

* Create header-only.yml

* Create package-managers.yml

* Update package-managers.yml

* Update getting-started.md

* Update getting-started.md

* Update header-only.yml

* Update header-only.yml

* Update header-only.yml

* Update header-only.yml

* use `jwt::algorithm::hs256`

 to link against openssl

* add crypto

* switch to ssl

* Update header-only.yml

* tidy

* lets install conan

* tidying

* Adding a CMake target to make the docs

* cleaning up repo root folder

* fix typo

* set docs flag as on

* update awesome doxy theme to latest

* Updated overrides for new version

* output folder and target name are changed

* add a few more docs

* white space

* cmake format

* playing with settings

* move algorithms - magically fixed missing structs

* playing with the idea of more refactoring

* more testing

* moved evp_handle def to special namespace for doxygen

* split evp class by it's self

* fix doc links

* playing with evp class to fix error -- no luck

* revert testing changes

* clang format

* cache should be container specific

* clean up includes

* combined class definition

* split algos but running in ci with older version

* trying slightly newer version of doxygen

* doxygen 196

* doxygen 197

* doxygen 198

* avoid regression in 198

* more docs

* playing with adding examples

* playing around with example support to see if I like

* docs include all the example files to be referenced in the code

* bump version to 0.7.0

* missing header

* devcontainer for testing openssl 3

* add test explorer

* add clang helpers

* there's a lot of package managers in 2023

* fixup colors with doxygen 1.10

* bump doxygen version

since my bug has been fixed

* move everything to one file (too many changes)

* update doxyfile to 1.10

* minimize diff

* fix extra line

* fix whitespace

* clean up dev container

* min changes

* cleanup

* better checking + warnings for doxygen

* whitespace

* adding in more docs

* fix spelling

* make sure traits appear

* trying to add snippets from examples

cant figure it out
doxygen/doxygen#10517

* Update faqs.md

* Delete .github/workflows/header-only.yml

* Delete .github/workflows/package-managers.yml

* Delete example/conan/CMakeLists.txt

* Delete example/conan/conanfile.txt

* Delete example/conan/main.cpp

* Delete example/conan/README.md

* Update nlohmann-json.cpp

* add updated getting started docs

first pass towards Thalhammer#319

* touch ups

* linking deprecated messages

* improve cmake with find_package examples

* fix code link color

* be more clear about turning off examples

good suggestion

Thalhammer#321 (comment)

* clarify openssl install and fixup fetch tag

* apply workaround from

doxygen/doxygen#10517 (comment)

* fix renamed types

* linting

* cross reference new docs

* trying new alert syntax

https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts

* move sections out of readme

trying to make it shorter and more approachable

* improve "getting started" readme section with a more through example

* sort out doubled "getting started"

second one in docs/ is just installation

* linter

* fixup english

* formatting

* whitespace

* tie in more examples with snippets

* minor touch ups

* Update signing.md

* JWT_BUILD_DOCS

* better cache string for new option

* word crafting

* word crafting

* add missing open-source-parsers/jsoncpp to traits list

* better github alert

* fixup new shields io start style

* improve docs cmake target name

* linter

---------

Co-authored-by: Christopher McArthur <christopherm@jfrog.com>
  • Loading branch information
prince-chrismc and Christopher McArthur authored Jan 10, 2024
1 parent a1ac7a0 commit 3ddac0c
Show file tree
Hide file tree
Showing 39 changed files with 1,238 additions and 568 deletions.
3 changes: 2 additions & 1 deletion .github/actions/install/cmake/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ runs:
id: cache-cmake
uses: actions/cache@v3
with:
path: cmake-${{ inputs.version }}${{ runner.name }}-${{ runner.os }}-${{ runner.arch }}-${{ job.container.id }}-cmake-${{ inputs.version }}
path: cmake-${{ inputs.version }}
key: ${{ runner.name }}-${{ runner.os }}-${{ runner.arch }}-${{ job.container.id }}-cmake-${{ inputs.version }}
- name: Build cmake
if: steps.cache-cmake.outputs.cache-hit != 'true'
run: |
Expand Down
19 changes: 0 additions & 19 deletions .github/overrides.css

This file was deleted.

14 changes: 9 additions & 5 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ssciwr/doxygen-install@v1
with:
version: "1.10.0"
- run: sudo apt install graphviz
- run: wget https://raw.githubusercontent.com/jothepro/doxygen-awesome-css/v1.6.1/doxygen-awesome.css
- run: wget https://raw.githubusercontent.com/jothepro/doxygen-awesome-css/v1.6.1/doxygen-awesome-sidebar-only.css
- uses: mattnotmitt/doxygen-action@v1
- name: deploy
- run: |
cmake . -DJWT_BUILD_DOCS=ON
cmake --build . --target jwt-docs
- if: github.event_name == 'push'
name: deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./doxy/html
publish_dir: ./build/html
force_orphan: true
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,5 @@ test
# ClangD cache files
.cache

doxy/
doxygen-awesome*.css

build/*
package-lock.json
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ project(jwt-cpp)

option(JWT_BUILD_EXAMPLES "Configure CMake to build examples (or not)" ON)
option(JWT_BUILD_TESTS "Configure CMake to build tests (or not)" OFF)
option(JWT_BUILD_DOCS "Adds a target for building the doxygen documentation" OFF)
option(JWT_ENABLE_COVERAGE "Enable code coverage testing" OFF)
option(JWT_ENABLE_FUZZING "Enable fuzz testing" OFF)

Expand Down Expand Up @@ -153,3 +154,7 @@ endif()
if(JWT_ENABLE_FUZZING)
add_subdirectory(tests/fuzz)
endif()

if(JWT_BUILD_DOCS)
add_subdirectory(docs)
endif()
124 changes: 59 additions & 65 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

[![Documentation Badge](https://img.shields.io/badge/Documentation-master-blue)](https://thalhammer.github.io/jwt-cpp/)

[![Stars Badge](https://img.shields.io/github/stars/Thalhammer/jwt-cpp)](https://github.com/Thalhammer/jwt-cpp/stargazers)
[![Stars Badge](https://img.shields.io/github/stars/Thalhammer/jwt-cpp?style=flat)](https://github.com/Thalhammer/jwt-cpp/stargazers)
[![GitHub release (latest SemVer including pre-releases)](https://img.shields.io/github/v/release/Thalhammer/jwt-cpp?include_prereleases)](https://github.com/Thalhammer/jwt-cpp/releases)
[![ConanCenter package](https://repology.org/badge/version-for-repo/conancenter/jwt-cpp.svg)](https://repology.org/project/jwt-cpp/versions)
[![Vcpkg package](https://repology.org/badge/version-for-repo/vcpkg/jwt-cpp.svg)](https://repology.org/project/jwt-cpp/versions)
Expand All @@ -19,121 +19,114 @@
[Windows]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/cross-platform/windows-latest/shields.json
[Cross-Platform]: https://github.com/Thalhammer/jwt-cpp/actions?query=workflow%3A%22Cross-Platform+CI%22

## Overview

A header only library for creating and validating [JSON Web Tokens](https://tools.ietf.org/html/rfc7519) in C++11. For a great introduction, [read this](https://jwt.io/introduction/).

The objective is to deliver a versatile and universally applicable collection of algorithms, classes, and data structures, fostering adaptability and seamless integration with other libraries that you may already be employing.

## Signature algorithms

jwt-cpp supports all the algorithms defined by the specifications. The modular design allows to easily add additional algorithms without any problems. If you need any feel free to create a pull request or [open an issue](https://github.com/Thalhammer/jwt-cpp/issues/new).
jwt-cpp comprehensively supports all algorithms specified in the standard. Its modular design facilitates the seamless [inclusion of additional algorithms](docs/signing.md#custom-signature-algorithms) without encountering any complications. Should you wish to contribute new algorithms, feel free to initiate a pull request or [open an issue](https://github.com/Thalhammer/jwt-cpp/issues/new).

For completeness, here is a list of all supported algorithms:

| HMSC | RSA | ECDSA | PSS | EdDSA |
|-------|-------|--------|-------|---------|
| ----- | ----- | ------ | ----- | ------- |
| HS256 | RS256 | ES256 | PS256 | Ed25519 |
| HS384 | RS384 | ES384 | PS384 | Ed448 |
| HS512 | RS512 | ES512 | PS512 | |
| | | ES256K | | |

## SSL Compatibility

In the name of flexibility and extensibility, jwt-cpp supports [OpenSSL](https://github.com/openssl/openssl), [LibreSSL](https://github.com/libressl-portable/portable), and [wolfSSL](https://github.com/wolfSSL/wolfssl). Read [this page](docs/ssl.md) for more details. These are the version which are currently being tested:

| OpenSSL | LibreSSL | wolfSSL |
|-------------------|----------------|----------------|
| ![1.0.2u][o1.0.2] | ![3.3.6][l3.3] | ![5.1.1][w5.1] |
| ![1.1.0i][o1.1.0] | ![3.4.3][l3.4] | ![5.2.0][w5.2] |
| ![1.1.1q][o1.1.1] | ![3.5.3][l3.5] | ![5.3.0][w5.3] |
| ![3.0.5][o3.0] | | |

> ℹ️ Note: A complete list of versions tested in the past can be found [here](https://github.com/Thalhammer/jwt-cpp/tree/badges).
[o1.0.2]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/openssl/1.0.2u/shields.json
[o1.1.0]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/openssl/1.1.0i/shields.json
[o1.1.1]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/openssl/1.1.1q/shields.json
[o3.0]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/openssl/3.0.5/shields.json
[l3.3]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/libressl/3.3.6/shields.json
[l3.4]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/libressl/3.4.3/shields.json
[l3.5]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/libressl/3.5.3/shields.json
[w5.1]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/wolfssl/5.1.1/shields.json
[w5.2]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/wolfssl/5.2.0/shields.json
[w5.3]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/wolfssl/5.3.0/shields.json

## Overview

There is no hard dependency on a JSON library. Instead, there's a generic `jwt::basic_claim` which is templated around type traits, which described the semantic [JSON types](https://json-schema.org/understanding-json-schema/reference/type.html) for a value, object, array, string, number, integer and boolean, as well as methods to translate between them.

```cpp
jwt::basic_claim<my_favorite_json_library_traits> claim(json::object({{"json", true},{"example", 0}}));
```
This allows for complete freedom when picking which libraries you want to use. For more information, [read this page](docs/traits.md)).
For your convenience there are serval traits implementation which provide some popular JSON libraries. They are:
[![picojson][picojson]](https://github.com/kazuho/picojson)
[![nlohmann][nlohmann]](https://github.com/nlohmann/json)
[![jsoncons][jsoncons]](https://github.com/danielaparker/jsoncons)
[![boostjson][boostjson]](https://github.com/boostorg/json)
[picojson]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/traits/kazuho-picojson/shields.json
[nlohmann]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/traits/nlohmann-json/shields.json
[jsoncons]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/traits/danielaparker-jsoncons/shields.json
[boostjson]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Thalhammer/jwt-cpp/badges/traits/boost-json/shields.json
In order to maintain compatibility, [picojson](https://github.com/kazuho/picojson) is still used to provide a specialized `jwt::claim` along with all helpers. Defining `JWT_DISABLE_PICOJSON` will remove this optional dependency. It's possible to directly include the traits defaults for the other JSON libraries. See the [traits examples](https://github.com/Thalhammer/jwt-cpp/tree/master/example/traits) for details.
As for the base64 requirements of JWTs, this library provides `base.h` with all the required implementation; However base64 implementations are very common, with varying degrees of performance. When providing your own base64 implementation, you can define `JWT_DISABLE_BASE64` to remove the jwt-cpp implementation.
## Getting Started

### Getting Started
Installation instructions can be found [here](docs/install.md).

Simple example of decoding a token and printing all [claims](https://tools.ietf.org/html/rfc7519#section-4) ([try it out](https://github.com/Thalhammer/jwt-cpp/tree/master/example/print-claims.cpp)):
A simple example is decoding a token and printing all of its [claims](https://tools.ietf.org/html/rfc7519#section-4) let's ([try it out](https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCIsInNhbXBsZSI6InRlc3QifQ.lQm3N2bVlqt2-1L-FsOjtR6uE-L4E9zJutMWKIe1v1M)):

```cpp
#include <jwt-cpp/jwt.h>
#include <iostream>

int main() {
std::string token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE";
std::string token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCIsInNhbXBsZSI6InRlc3QifQ.lQm3N2bVlqt2-1L-FsOjtR6uE-L4E9zJutMWKIe1v1M";
auto decoded = jwt::decode(token);

for(auto& e : decoded.get_payload_json())
std::cout << e.first << " = " << e.second << std::endl;
}
```

You can build and run [this example](example/print-claims.cpp) locally after cloning the repository.
Running some commands, we can see the contents of the [JWT payload](https://datatracker.ietf.org/doc/html/rfc7519#section-3)

```sh
cmake .
cmake --build . --target print-claims
./print-claims
# iss = "auth0"
# sample = "test"
```

You'll very quickly notice JWT are not encrypted but rather cryptographically signed to
provide [non-repudiation](https://csrc.nist.gov/glossary/term/non_repudiation).

In order to verify a token you first build a verifier and use it to verify a decoded token.

```cpp
auto verifier = jwt::verify()
.allow_algorithm(jwt::algorithm::hs256{ "secret" })
.with_issuer("auth0");
.with_issuer("auth0")
.with_claim("sample", jwt::claim(std::string("test")));
.allow_algorithm(jwt::algorithm::hs256{"secret"})

verifier.verify(decoded_token);
```
The created verifier is stateless so you can reuse it for different tokens.
The verifier is stateless so you can reuse it for different tokens.
Creating a token (and signing) is equally as easy.
Creating the token above (and signing it) is equally as easy.
```cpp
auto token = jwt::create()
.set_issuer("auth0")
.set_type("JWS")
.set_issuer("auth0")
.set_payload_claim("sample", jwt::claim(std::string("test")))
.sign(jwt::algorithm::hs256{"secret"});
```

> To see more examples working with RSA public and private keys, visit our [examples](https://github.com/Thalhammer/jwt-cpp/tree/master/example)!
If you are looking to issue or verify more unique tokens, checkout out the [examples](https://github.com/Thalhammer/jwt-cpp/tree/master/example) working with RSA public and private keys, elliptic curve tokens, and much more!

### Configuration Options

Building on the goal of providing flexibility.

#### SSL Compatibility

jwt-cpp supports [OpenSSL](https://github.com/openssl/openssl), [LibreSSL](https://github.com/libressl-portable/portable), and [wolfSSL](https://github.com/wolfSSL/wolfssl). For a listed of tested versions, check [this page](docs/ssl.md) for more details.

#### JSON Implementation

There is no strict reliance on a specific JSON library in this context. Instead, the jwt-cpp utilizes a generic `jwt::basic_claim` that is templated based on type trait. This trait provides the semantic [JSON types](https://json-schema.org/understanding-json-schema/reference/type.html) for values, objects, arrays, strings, numbers, integers, and booleans, along with methods to seamlessly translate between them.

This design offers flexibility in choosing the JSON library that best suits your needs. To leverage one of the provided JSON traits, refer to [docs/traits.md](docs/traits.md#selecting-a-json-library) for detailed guidance.

##### Providing your own JSON Traits

```cpp
jwt::basic_claim<my_favorite_json_library_traits> claim(json::object({{"json", true},{"example", 0}}));
```
To learn how to writes a trait's implementation, checkout the [these instructions](docs/traits.md#providing-your-own-json-traits)
### Providing your own JSON Traits
#### Base64 Options
To learn how to writes a trait's implementation, checkout the [these instructions](docs/traits.md)
With regard to the base64 specifications for JWTs, this library includes `base.h` encompassing all necessary variants. While the library itself offers a proficient base64 implementation, it's worth noting that base64 implementations are widely available, exhibiting diverse performance levels. If you prefer to use your own base64 implementation, you have the option to define `JWT_DISABLE_BASE64` to exclude the jwt-cpp implementation.
## Contributing
If you have an improvement or found a bug feel free to [open an issue](https://github.com/Thalhammer/jwt-cpp/issues/new) or add the change and create a pull request. If you file a bug please make sure to include as much information about your environment (compiler version, etc.) as possible to help reproduce the issue. If you add a new feature please make sure to also include test cases for it.
If you have suggestions for improvement or if you've identified a bug, please don't hesitate to [open an issue](https://github.com/Thalhammer/jwt-cpp/issues/new) or contribute by creating a pull request. When reporting a bug, provide comprehensive details about your environment, including compiler version and other relevant information, to facilitate issue reproduction. Additionally, if you're introducing a new feature, ensure that you include corresponding test cases to validate its functionality.
## Dependencies
### Dependencies
In order to use jwt-cpp you need the following tools.
Expand All @@ -152,4 +145,5 @@ In order to build the test cases you also need
See the [FAQs](docs/faqs.md) for tips.
## Conference Coverage
[![CppCon](https://img.youtube.com/vi/Oq4NW5idmiI/0.jpg)](https://www.youtube.com/watch?v=Oq4NW5idmiI)
1 change: 1 addition & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
doxygen-awesome*.css
23 changes: 23 additions & 0 deletions docs/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
file(DOWNLOAD https://raw.githubusercontent.com/jothepro/doxygen-awesome-css/v2.2.1/doxygen-awesome.css
${CMAKE_CURRENT_LIST_DIR}/doxygen-awesome.css
EXPECTED_HASH SHA256=9b5549928906e9974cc12dcdde9265e016dc2388ec72d5aa3209f4870914a0c8)
file(DOWNLOAD https://raw.githubusercontent.com/jothepro/doxygen-awesome-css/v2.2.1/doxygen-awesome-sidebar-only.css
${CMAKE_CURRENT_LIST_DIR}/doxygen-awesome-sidebar-only.css
EXPECTED_HASH SHA256=998328b27193b7be007a431bc9be1a6f6855ff4d8fa722ecfdfed79a8931409f)

execute_process(COMMAND doxygen --version RESULT_VARIABLE DOXYGEN_VERSION_RESULT
OUTPUT_VARIABLE DOXYGEN_VERSION_RAW_OUTPUT)
if(NOT DOXYGEN_VERSION_RESULT EQUAL 0)
message(AUTHOR_WARNING "Unable to get the version of doxygen")
else()
# Extracts the version from the output of the command run before
string(REGEX MATCH "^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)" DOXYGEN_VERSION_OUTPUT
"${DOXYGEN_VERSION_RAW_OUTPUT}")
message(STATUS "doxygen version detected : ${DOXYGEN_VERSION_OUTPUT}")
endif()

add_custom_target(jwt-docs COMMAND doxygen ${CMAKE_CURRENT_LIST_DIR}/Doxyfile WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
SOURCES ${CMAKE_CURRENT_LIST_DIR}/Doxyfile BYPRODUCTS ${CMAKE_BINARY_DIR}/html/index.html)
add_custom_command(
TARGET jwt-docs POST_BUILD COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --cyan
"You can prview the documentation: ${CMAKE_BINARY_DIR}/html/index.html")
Loading

0 comments on commit 3ddac0c

Please sign in to comment.