Appearance
Authentication (JWT)
The framework supports JWT-based authentication with signing and optional encryption.
JWT Configuration
Configure signing and encryption keys in the configuration object. Generate keys using the keys_generator CLI tool.
cpp
using namespace framework;
configuration config;
config.jwt_.keys_.signature_.store(
std::make_shared<const std::string>("base64:UtwkdboUSM8rGQREA4TmO+rTOeSlJJKrO2NKUSAjz6Q="));
config.jwt_.keys_.encryption_.store(
std::make_shared<const std::string>("base64:8wDSwRRPsExIQyX1U97jh9A9Ed8jxuEe/K7J8eu5jWY="));| Config Field | Purpose |
|---|---|
jwt_.keys_.signature_ | Key used to sign and verify JWT integrity. |
jwt_.keys_.encryption_ | Key used to encrypt and decrypt the JWT payload. |
auth::to_string(claims, sign_key, enc_key, duration) — Generating a Token
Creates a signed (and optionally encrypted) JWT string from a claims object.
cpp
#include <framework/support/auth.hpp>
using namespace framework;
using namespace framework::support::auth;
claims claims;
claims.subject_ = "user123";
claims.expiration_ = std::time(nullptr) + 3600; // 1 hour from now
claims.grants_["channels"] = {"read", "write"};
claims.grants_["admin"] = {"all"};
auto token = to_string(
claims,
config.jwt_.keys_.signature_.load(),
config.jwt_.keys_.encryption_.load(),
3600
);| Param | Description |
|---|---|
payload | A claims struct or boost::json::object with the token data. |
signature_key | Base64-encoded signing key. |
encryption_key | Base64-encoded encryption key. |
duration | Token lifetime in seconds (default: 86400). |
Overload with JSON object
cpp
auto payload = boost::json::object{
{"sub", "user123"},
{"exp", std::time(nullptr) + 3600},
{"grants", {{"channels", {"read", "write"}}}}
};
auto token = to_string(payload, sign_key, enc_key, 3600);auth::from_string(token, sign_key, enc_key) — Verifying a Token
Decodes, decrypts, and verifies a JWT. Returns a result struct.
cpp
auto result = from_string(
token,
config.jwt_.keys_.signature_.load(),
config.jwt_.keys_.encryption_.load()
);
if (result.is_valid()) {
auto& claims = result.get_claims();
fmt::println("Authenticated user: {}", claims.subject_);
}The result struct
cpp
struct result {
bool valid_; // True if token is valid
value payload_; // Raw JSON payload
std::optional<claims> claims_data_; // Parsed claims (if valid)
};| Method | Description |
|---|---|
is_valid() | Returns true if the token was successfully verified. |
get_claims() | Returns the parsed claims struct. |
The claims Struct
cpp
struct claims {
std::string subject_; // User ID ("sub")
long expiration_; // Expiration timestamp ("exp")
std::map<std::string, std::vector<std::string>, std::less<>> grants_; // Permissions
};Example grants:
json
{
"sub": "user123",
"exp": 1715000000,
"grants": {
"channels": ["read", "write"],
"admin": ["all"],
"cache:user:42:*": ["read"]
}
}jwt::has_grant(resource, permission) — Grant Checking
cpp
framework::support::auth::jwt jwt;
jwt.set_token(token);
if (jwt.has_grant("channels:private-chat-42", "read")) {
// Authorized to read private-chat-42
}Route Protection
Mark routes as requiring authentication:
cpp
using namespace framework;
using namespace framework::clients::http;
app.register_endpoint(
http_verb_t::get,
"/admin/stats",
handler,
nullptr, // no validator
gates::is_admin_all, // gate (runs after JWT verification)
true // requires JWT authentication
);When requires_auth is true, the framework extracts the JWT from the Authorization header and verifies it before the handler runs.
Client-side: Send the token in the HTTP header:
Authorization: Bearer <token>