JWT Bearer Authorization for HTTP servers

Use a compact JWT in an HTTP Authorization: Bearer header to protect an HTTP endpoint. Mongoose extracts the token with mg_http_creds() and verifies it with the JWT API.

For a complete runnable example, see JWT Bearer authentication.

Verify a Bearer token

Check the header scheme before calling mg_http_creds(): that function also accepts Basic credentials, an access_token cookie, and an access_token query parameter.

static bool authorized(struct mg_http_message *hm) {
  struct mg_str *auth = mg_http_get_header(hm, "Authorization");
  char user[1], token[512], claims[256];
  struct mg_jwt_opts opts = {.secret = mg_str("replace-with-a-secret")};
  size_t n;

  if (auth == NULL || !mg_match(*auth, mg_str("Bearer *"), NULL)) return false;
  mg_http_creds(hm, user, sizeof(user), token, sizeof(token));
  n = mg_jwt_verify_hs256(mg_str(token), &opts, claims, sizeof(claims));
  if (n == 0 || n >= sizeof(claims)) return false;
  return mg_json_get_long(mg_str_n(claims, n), "$.admin", 0) == 1;
}

static void fn(struct mg_connection *c, int ev, void *ev_data) {
  if (ev == MG_EV_HTTP_MSG) {
    struct mg_http_message *hm = (struct mg_http_message *) ev_data;
    if (!authorized(hm)) {
      mg_http_reply(c, 401, "WWW-Authenticate: Bearer\r\n", "Unauthorized\n");
    } else {
      mg_http_reply(c, 200, "", "OK\n");
    }
  }
}

mg_jwt_verify_hs256() returns the decoded claims length, or 0 if the token is malformed, uses another algorithm, has an invalid signature, or does not fit in the buffer. The decoded claims are not NUL-terminated; pass the returned length to mg_str_n() as shown above.

Validate authorization claims

Signature verification establishes that a holder of the signing key created the token. It does not enforce the token's authorization policy. After a successful verification, validate every claim required by the application:

  • expiry (exp) and not-before (nbf)
  • issuer (iss) and audience (aud)
  • subject, role, scope, or another application-specific permission

Use a trusted clock for time-based claims. For key rotation, choose the verification key through trusted application state; do not choose an algorithm from an untrusted JWT header.