I am getting a json web token from a web service, which when decoded returns something like this:
{
"exp": 1572468916,
"iat": 1572468316,
"iss": "https://ccc/auth/realms/yyy",
"aud": "xxx-api",
[...]
According to Section 2 terminalogy the NumericDate data type correspond to a "Seconds Since the Epoch"
So I convert it to a Javascript Date like this:
new Date(1572468316 * 1000)
Date Wed Oct 30 2019 17:45:16 GMT-0300 (Argentina Standard Time)
The problem is that my current time is:
new Date()
Date Wed Oct 30 2019 14:45:19 GMT-0300 (Argentina Standard Time)
Efectively, the current time is the one returned from new Date()
(that is 14:45, no 17:45)
I guess it has something to do with the GMT, but I don´t know how to handle it.
I want to convert the iat property (and obviously the exp property too) to the current time in order to pare it to new Date()
to find out if the token has already expired or not.
So how can I convert a NumericDate from a json web token iat/exp property to my local time for parison?
I am getting a json web token from a web service, which when decoded returns something like this:
{
"exp": 1572468916,
"iat": 1572468316,
"iss": "https://ccc/auth/realms/yyy",
"aud": "xxx-api",
[...]
According to Section 2 terminalogy the NumericDate data type correspond to a "Seconds Since the Epoch"
So I convert it to a Javascript Date like this:
new Date(1572468316 * 1000)
Date Wed Oct 30 2019 17:45:16 GMT-0300 (Argentina Standard Time)
The problem is that my current time is:
new Date()
Date Wed Oct 30 2019 14:45:19 GMT-0300 (Argentina Standard Time)
Efectively, the current time is the one returned from new Date()
(that is 14:45, no 17:45)
I guess it has something to do with the GMT, but I don´t know how to handle it.
I want to convert the iat property (and obviously the exp property too) to the current time in order to pare it to new Date()
to find out if the token has already expired or not.
So how can I convert a NumericDate from a json web token iat/exp property to my local time for parison?
Share Improve this question edited Oct 7, 2021 at 13:39 CommunityBot 11 silver badge asked Oct 30, 2019 at 17:53 opensasopensas 63.8k90 gold badges265 silver badges415 bronze badges 4-
1
Maybe try subtracting 3 hours worth of seconds from the timestamp? More dynamically, you can use
(new Date()).getTimezoneOffset()
to get the number of minutes away from GMT you are and subtract that times 60. Let me know if that works; if it does, I'll post it as an official answer. – IceMetalPunk Commented Oct 30, 2019 at 17:57 -
I can confirm that the approach works ok, to make it generic I hace to transform the NumericDate to date and then extract the getTimezonOffset, like this:
const d_utc = new Date(1572468316 * 1000)
and thenconst d_local = new Date(d_utc.valueOf() - (d_utc.getTimezoneOffset() * 60 * 1000))
so that d_utc =Date Wed Oct 30 2019 17:45:16 GMT-0300 (Argentina Standard Time)
and d_local =Date Wed Oct 30 2019 14:45:16 GMT-0300 (Argentina Standard Time)
– opensas Commented Oct 30, 2019 at 21:48 - go ahead and post the answer to that I can accept it ;-) – opensas Commented Oct 30, 2019 at 21:48
- 2 Sorry, but that is not the correct approach. I will post an answer shortly explaining. – Matt Johnson-Pint Commented Oct 30, 2019 at 22:28
1 Answer
Reset to default 5The iat
and exp
values are indeed in terms of seconds since the Unix epoch. Since the Unix epoch is UTC based, so are these values. You are converting them to Date
objects correctly.
var iat = new Date(1572468316 * 1000);
var exp = new Date(1572468916 * 1000);
console.log(iat.toISOString()); //=> "2019-10-30T20:45:16.000Z"
console.log(exp.toISOString()); //=> "2019-10-30T20:55:16.000Z"
The toISOString
function emits a string in ISO 8601 format, presented as UTC (as indicated by the trailing Z
character).
The output format you gave in your question is what would happen when calling the toString
function, or when directly logging a Date
object in an environment that chooses to log the toString
output. Since different environments can emit different formats (some in local time, some in UTC, some in ISO 8601, some in a non-standard format) - it's not remended to directly log a Date
object.
The output from toISOString
shows that the JWT was valid for 10 minutes, from 2019-10-30 20:45:16 UTC to 2019-10-30 20:55:16 UTC. There is no other way to interpret these results.
Your local time output shows a three-hour conversion, which would correctly correspond to a UTC-3 time zone offset, again confirming they values are being parsed correctly.
If that is not what you expected, then the token wasn't issued correctly. One of two things is going on:
There could be a bug in the code that is generating the JWT, in that it is using a local time instead of UTC as a basis for creating the timestamp.
The server running the code where the JWT was generated could have its clock set incorrectly.
The second one is more plausible. For example, this can happens when a server administrator sets the the time zone to UTC but sets the clock based on the local time. Instead, ensure the clock on the server is set to synchronize its time automatically from the Internet, and the problem will likely go away.
Regarding the approach mentioned in the question ments - don't do that. Subtracting the time zone offset in that way doesn't adjust correctly for time zones, but rather it picks a different point in time. It may appear to deliver the correct results, but you will find edge cases around daylight saving time transitions in many time zones, and you will have a problem once the JWTs start being generated with the correct values.