JSON Web Tokens (JWT)

Mongoose can sign and verify compact JSON Web Tokens (JWTs). HS256 is available in every build. ES256 is available when MG_TLS == MG_TLS_BUILTIN.

Full example: JWT Bearer authentication

struct mg_jwt_opts

struct mg_jwt_opts {
  struct mg_str claims;  // JSON payload
  struct mg_str header;  // Extra header members, no braces; alg/typ are set
  struct mg_str kid;     // Key ID protected header
  struct mg_str secret;  // HS256 secret
  const uint8_t *private_key;  // ES256 private key (MG_TLS_BUILTIN only)
  const uint8_t *public_key;   // ES256 public key (MG_TLS_BUILTIN only)
};

JWT options structure:

  • claims - JSON claims to sign
  • header - additional protected-header members, without surrounding braces
  • kid - optional protected-header key ID
  • secret - shared secret for HS256
  • private_key - 32-byte ES256 private key for signing
  • public_key - 64-byte ES256 public key for verification

Mongoose always writes the alg and typ protected-header members. kid and header are used when signing only; verification selects its algorithm explicitly and does not select a key from kid.

mg_jwt_sign_hs256()

size_t mg_jwt_sign_hs256(const struct mg_jwt_opts *opts, char *buf,
                         size_t len);

Sign JSON claims as a compact JWT using HMAC-SHA256.

Parameters:

  • opts - JWT options. Set claims and secret
  • buf - buffer to receive the JWT
  • len - size of buf

Return value: JWT length, or 0 on error. The output is not NUL-terminated.

Usage example:

char jwt[256];
struct mg_jwt_opts opts = {
    .claims = mg_str("{\"sub\":\"admin\"}"),
    .secret = mg_str("replace-with-a-secret"),
};
size_t n = mg_jwt_sign_hs256(&opts, jwt, sizeof(jwt));
if (n > 0 && n < sizeof(jwt)) jwt[n] = '\0';

mg_jwt_verify_hs256()

size_t mg_jwt_verify_hs256(struct mg_str jwt, const struct mg_jwt_opts *opts,
                           char *buf, size_t len);

Verify a compact HS256 JWT and decode its JSON claims.

Parameters:

  • jwt - compact JWT to verify
  • opts - JWT options. Set secret
  • buf - buffer to receive decoded claims
  • len - size of buf

Return value: claims length, or 0 if the JWT is malformed, has a different algorithm, has an invalid signature, or does not fit in buf. The claims are not NUL-terminated.

Usage example:

char claims[256];
struct mg_jwt_opts opts = {.secret = mg_str("replace-with-a-secret")};
size_t n = mg_jwt_verify_hs256(mg_str(jwt), &opts, claims, sizeof(claims));
if (n > 0 && mg_json_get_long(mg_str_n(claims, n), "$.admin", 0) == 1) {
  // Valid administrator token
}

Notes: The function verifies the JWT format, algorithm, and signature. Validate expiry, issuer, audience, and application authorization claims separately.

mg_jwt_sign_es256()

size_t mg_jwt_sign_es256(const struct mg_jwt_opts *opts, char *buf,
                         size_t len);

Sign JSON claims as a compact JWT using ECDSA P-256 and SHA-256.

Parameters:

  • opts - JWT options. Set claims and private_key
  • buf - buffer to receive the JWT
  • len - size of buf

Return value: JWT length, or 0 on error. The output is not NUL-terminated.

Usage example:

extern uint8_t private_key[32];  // Application-provisioned P-256 private key
char jwt[256];
struct mg_jwt_opts opts = {
    .claims = mg_str("{\"sub\":\"admin\"}"),
    .private_key = private_key,
};
size_t n = mg_jwt_sign_es256(&opts, jwt, sizeof(jwt));
if (n > 0 && n < sizeof(jwt)) jwt[n] = '\0';

Notes: Available only when MG_TLS == MG_TLS_BUILTIN.

mg_jwt_verify_es256()

size_t mg_jwt_verify_es256(struct mg_str jwt, const struct mg_jwt_opts *opts,
                           char *buf, size_t len);

Verify a compact ES256 JWT and decode its JSON claims.

Parameters:

  • jwt - compact JWT to verify
  • opts - JWT options. Set public_key
  • buf - buffer to receive decoded claims
  • len - size of buf

Return value: claims length, or 0 if the JWT is malformed, has a different algorithm, has an invalid signature, or does not fit in buf. The claims are not NUL-terminated.

Usage example:

extern uint8_t public_key[64];  // Application-provisioned P-256 public key
char claims[256];
struct mg_jwt_opts opts = {.public_key = public_key};
size_t n = mg_jwt_verify_es256(mg_str(jwt), &opts, claims, sizeof(claims));
if (n > 0 && mg_json_get_long(mg_str_n(claims, n), "$.admin", 0) == 1) {
  // Valid administrator token
}

Notes: Available only when MG_TLS == MG_TLS_BUILTIN. Validate expiry, issuer, audience, and application authorization claims separately.