JWT (Beginner Guide)
Welcome 👋
This page teaches you how to use JWT authentication in Vix.cpp with minimal examples.
JWT is useful when you want:
- stateless auth (no server sessions)
- API tokens for mobile apps and CLIs
- simple role based access (admin, user, etc.)
- permissions like
products:write
What is a JWT?
A JWT is just a string with 3 parts:
header.payload.signature
- header says which algorithm is used (example: HS256)
- payload contains claims (sub, roles, perms)
- signature proves the token was created using your secret
In Vix.cpp, JWT middleware checks:
- the token exists in
Authorization: Bearer <token> - signature is valid for your secret
- (optionally) exp is valid
1) Smallest JWT protected route (App)
This is the simplest pattern:
/is public/securerequires a Bearer token
#include <iostream>
#include <string>
#include <vix.hpp>
#include <vix/middleware/app/presets.hpp>
using namespace vix;
static const std::string kToken =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
"eyJzdWIiOiJ1c2VyMTIzIiwicm9sZXMiOlsiYWRtaW4iXX0."
"3HK5b1sXMbxkjC3Tllwtcuzxm-1OI0D184Fuav0-XQo"; // HS256, secret=dev_secret
int main()
{
App app;
// Protect only /secure (verify_exp=false for beginner demo)
app.use("/secure", middleware::app::jwt_dev("dev_secret"));
app.get("/", [](Request &, Response &res)
{
res.send(
"JWT example:\n"
" GET /secure requires Bearer token.\n"
"\n"
"Try:\n"
" curl -i http://localhost:8080/secure\n"
" curl -i -H \"Authorization: Bearer <TOKEN>\" http://localhost:8080/secure\n"
);
});
app.get("/secure", [](Request &req, Response &res)
{
auto &claims = req.state<vix::middleware::auth::JwtClaims>();
res.json({
"ok", true,
"sub", claims.subject,
"roles", claims.roles
});
});
std::cout
<< "Server: http://localhost:8080/\n"
<< "Secure: http://localhost:8080/secure\n\n"
<< "Token:\n" << kToken << "\n";
app.run(8080);
return 0;
}Test with curl
Run:
vix run jwt_app_simple.cppNo token:
curl -i http://localhost:8080/secureWith token:
TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyMTIzIiwicm9sZXMiOlsiYWRtaW4iXX0.3HK5b1sXMbxkjC3Tllwtcuzxm-1OI0D184Fuav0-XQo"
curl -i -H "Authorization: Bearer $TOKEN" http://localhost:8080/secure2) Reading JWT claims inside your handler
After JWT middleware succeeds, claims are stored in request state:
auto &claims = req.state<vix::middleware::auth::JwtClaims>();
// Common fields:
claims.subject // "sub"
claims.roles // "roles" (array)So you can do:
app.get("/secure", [](Request &req, Response &res)
{
auto &claims = req.state<vix::middleware::auth::JwtClaims>();
res.json({
"ok", true,
"sub", claims.subject,
"roles", claims.roles
});
});3) Common beginner mistakes
Secret mismatch
The token is signed with a secret. Your middleware must use the same secret.Forgetting the Bearer prefix
It must be:
Authorization: Bearer <token>
Not enabling JWT in build
If your build has a flag likeVIX_ENABLE_JWT, you must enable it, otherwise middleware might not exist.Forgetting expiration handling
For beginner demos we useverify_exp=false. In production, you usually wantverify_exp=trueand anexpclaim.
Summary
- Protect a prefix:
app.use("/secure", jwt_dev("secret")) - Send token in header:
Authorization: Bearer <token> - Read claims from request state after middleware success
- For dev, use a token generator tool