Skip to content

fix: accept non-string values in Header extras#496

Open
kp-timo-beyel wants to merge 1 commit intoKeats:masterfrom
kp-timo-beyel:fix/header-extras-non-string-values
Open

fix: accept non-string values in Header extras#496
kp-timo-beyel wants to merge 1 commit intoKeats:masterfrom
kp-timo-beyel:fix/header-extras-non-string-values

Conversation

@kp-timo-beyel
Copy link
Copy Markdown

Summary

  • Change Header.extras from HashMap<String, String> to HashMap<String, serde_json::Value>
  • decode_header / decode now accept JWT headers with non-string custom fields (e.g. "uid": 180444)

Problem

When a JWT header contains a non-standard field with a non-string value such as:

{"typ": "JWT", "alg": "RS256", "kid": "...", "uid": 180444}

decode_header fails with a deserialization error because serde cannot coerce the integer 180444 into a String for the #[serde(flatten)] pub extras: HashMap<String, String> field.

JOSE headers can legitimately carry arbitrary JSON values in custom fields, so the extras map should accept any JSON value.

Fix

Change the type of Header.extras from HashMap<String, String> to HashMap<String, serde_json::Value>.

Breaking change

Consumers that read from Header.extras directly now receive serde_json::Value instead of String. For string extras, .as_str().unwrap() (or pattern matching) is needed:

// Before
let v: &String = header.extras.get("custom").unwrap();

// After  
let v: &str = header.extras.get("custom").unwrap().as_str().unwrap();

Test plan

  • Existing tests updated and passing
  • New test decode_token_with_non_string_extra_header verifies integer header values are accepted
  • Example and benchmark updated

…ing, serde_json::Value>

The `extras` field on `Header` used `HashMap<String, String>`, which
caused `decode_header` and `decode` to fail when the JWT header contained
non-string values (e.g. `"uid": 180444`). Since JOSE headers can
legitimately carry arbitrary JSON values in custom fields, this changes
the type to `HashMap<String, serde_json::Value>` so that integers,
booleans, arrays, and objects are accepted.

This is a breaking change for consumers that read from `Header.extras`
directly — they now receive `serde_json::Value` instead of `String`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant