Unable to set Exp and Iat for JWT correctly

Based on what Krzysztof Sztompka posted, I could get the Ext to show the correct expiry date. (my original requirement was for 1 hour in the future)

To keep track of the change vs previous mistakes, I won't update the code above, so here is what I changed:

var d = new Date();

var calculatedExpiresIn = (((d.getTime()) + (60 * 60 * 1000)) - (d.getTime() - d.getMilliseconds()) / 1000);

var token = jwt.sign({"id": user._id}, configGeneral.JWT, { expiresIn: calculatedExpiresIn });

The console.log's will now show that the Ext is as I wanted it, now + 1 hour.

To get the Iat to show the correct date (after setting it in the sign function and then sanity checking it in the decode function), I had to set it as part of the payload. I got my answer here

So finally to get the Iat to show correctly I added it to the payload as shown here:

var token = jwt.sign({"id": user._id, "iat": (new Date().getTime())}, configGeneral.JWT, { expiresIn: calculatedExpiresIn });

This gives an output of:

{ id: '56253091fe0397c80133f3e4',
  iat: 1445763099706,
  exp: 1445766699705 }
Sun Oct 25 2015 11:51:39 GMT+0200 (South Africa Standard Time)
Sun Oct 25 2015 10:51:39 GMT+0200 (South Africa Standard Time)

This is the unencoded JWT which I will passed back to the users when they have signed in successfully and will allow me to check whether the JWT they have to pass as every future request is still valid and hasn't expired yet.


This:

new Date().getTime()

give you time in miliseconds. But time in jwt token (iat, exp) is in seconds, therefore we have to divide result by 1000.

var actualTimeInSeconds = new Date().getTime()/1000;

How to get some time in seconds from now:

(new Date().getTime() + someTimeInSeconds * 1000)/1000

If you need 1 hour from now:

(new Date().getTime() + 60 * 60 * 1000)/1000

because 1h = 60min * 60 s

And at this moment you have time in seconds from jwt token and calculated time in seconds. You should only compare this values.

Precisely in your situation you should compare jwt token time with your actual time in seconds. If jwt token expiration time is greater then actual time it means that it is still valid. From docs of jwt token:

The processing of the exp claim requires that the current date/time MUST be before the expiration date/time listed in the exp claim.

Edit:

To get coorect date from iat, multiply value by 1000 and add to new Date constructor:

new Date(iat*1000)

The epoch created by the library is Unix epoch time & you can check the jwt iat & exp values in any website (like this for example) & you will find them valid

For example, the iat in your question 1445714161 is GMT: Saturday, 24 October 2015 19:16:01

You exp was 1445717761 which is GMT: Saturday, 24 October 2015 20:16:01

So it was 1 hour later which was your objective from the beginning

if you try in javascript new Date(1445714161) you will get a wrong time

So the easiest way to create the iat (created automatically) & exp claims as per the documentation of the jsonwebtoken library here

You can set the expiry easily this way

jwt.sign({
  data: 'foobar'
}, 'secret', { expiresIn: 60 * 60 });

or even better:

jwt.sign({
  data: 'foobar'
}, 'secret', { expiresIn: '1h' });

This will put the exp claim in the jwt as follows, with the correct unix epoch time for both iat & exp (with expiry 1 hour later than issued at time), so for example it will be like this (which can be verified easily in jwt libraries):

{
  "data": "foobar",
  "iat": 1539549664,
  "exp": 1539553264
}

Note that the above expiresIn option is specific for jsonwebtoken library & a more generic way will be like this:

jwt.sign({
  exp: Math.floor(Date.now() / 1000) + (60 * 60),
  data: 'foobar'
}, 'secret');