-
-
Notifications
You must be signed in to change notification settings - Fork 727
Open
Description
Summary
When using jwt.encode function, known time claims such as exp, iat and nbf lose microseconds precision if their value is a datetime.
This happens because the underlying structure used by utctimetuple and timegm functions does not store time units below full seconds (see tm struct at https://pubs.opengroup.org/onlinepubs/9799919799/).
Culprit is line at
Lines 127 to 130 in dd44834
| for time_claim in ["exp", "iat", "nbf"]: | |
| # Convert datetime to a intDate value in known time-format claims | |
| if isinstance(payload.get(time_claim), datetime): | |
| payload[time_claim] = timegm(payload[time_claim].utctimetuple()) |
Example
Code
import datetime as dt
import jwt
dt_iat = dt.datetime(2025, 1, 1, 0, 0, 0, 123456, dt.UTC)
result = jwt.decode(jwt.encode({'iat': dt_iat}, 'secret'), 'secret', algorithms = ['HS256'])
decoded_dt_iat = dt.datetime.fromtimestamp(result['iat'], tz=dt.UTC)
print(f'Original: {dt_iat}')
print(f'Decoded: {decoded_dt_iat}')
print(f'Original timestamp: {dt_iat.timestamp()}')
print(f'Decoded timestamp: {decoded_dt_iat.timestamp()}')returns
Original: 2025-01-01 00:00:00.123456+00:00
Decoded: 2025-01-01 00:00:00+00:00
Original timestamp: 1735689600.123456
Decoded timestamp: 1735689600.0
currently at master (dd44834).
It should return
Original: 2025-01-01 00:00:00.123456+00:00
Decoded: 2025-01-01 00:00:00.123456+00:00
Original timestamp: 1735689600.123456
Decoded timestamp: 1735689600.123456
System Information
$ python -m jwt.help
{
"cryptography": {
"version": "46.0.3"
},
"implementation": {
"name": "CPython",
"version": "3.13.11"
},
"platform": {
"release": "6.12.63-1-lts",
"system": "Linux"
},
"pyjwt": {
"version": "2.10.1"
}
}
I will submit a PR shortly to tackle this.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels