DRobinson
DRobinson

Reputation: 295

Why does my JWT expiresIn value change between sending it from the server and receiving it on the front-end?

I set my token expiry date on the server and console.log out the value to check: server expiry date

However, when I check the value on my React front-end, I get this value:

front-end expiry date

I don't alter the expiry date in any way but the value is changed dramatically between sending it and receiving it.

Does anyone have any ideas?

Server code

const d = new Date();
        console.log(
          'current date: ',
          moment(d.getTime()).format('YYYY-MM-DD HH:mm:ss')
        );
        /*const calculatedExpiresIn =
          d.getTime() +
          60 * 60 * 1000 -
          (d.getTime() - d.getMilliseconds()) / 1000;*/
        const calculatedExpiresIn = d.getTime() + 60 * 60 * 1000;
        console.log(
          'calculatedExpiresIn: ',
          moment(calculatedExpiresIn).format('YYYY-MM-DD HH:mm:ss')
        );
        console.log('calculatedExpiresIn: ', calculatedExpiresIn);

        const iat = d.getTime();
        const user = ok([
          {
            id: res[0].id,
            token: jwt.sign(
              {
                id: res[0].id,
                email: res[0].email,
                firstName: res[0].firstName,
                surname: res[0].surname,
                role: res[0].role,
                iat: iat,
              },
              config.secret,
              {
                expiresIn: calculatedExpiresIn,
              }
            ),
          },
        ]);

Front-end code

validateSession() {
    let token = sessionStorage.getItem('unikey');
    const d = new Date();

    if (token && token !== undefined) {
      let decodedToken = jwtDecode(token);
      /*console.log('decodedToken: ', decodedToken);
      console.log(
        'decodedToken iat date: ',
        moment(decodedToken.iat).format('YYYY-MM-DD HH:mm:ss')
      );*/
      console.log(
        'decodedToken expiry date: ',
        moment(decodedToken.exp).format('YYYY-MM-DD HH:mm:ss')
      );
      console.log(
        'current date: ',
        moment(d.getTime()).format('YYYY-MM-DD HH:mm:ss')
      );
      console.log('decodedToken expiry date: ', decodedToken.exp);
      console.log('current date: ', d.getTime());
      console.log('Time difference: ', decodedToken.exp - d.getTime());

      if (d > decodedToken.exp) {
        console.log('Time is up...');
        this.terminateSession();
        return false;
      }
      return true;
    } else {
      // There is no token so session is automatically invalid
      this.terminateSession();
      return false;
    }
  }

Token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NDQsImVtYWlsIjoidGVzdEBlbWFpbC5jb20iLCJmaXJzdE5hbWUiOiJ0ZXN0Iiwic3VybmFtZSI6InVzZXIiLCJyb2xlIjoiYWdlbnQiLCJpYXQiOjE2MTg1NTYyOTE3MzAsImV4cGlyeSI6MTYxODU1OTg5MTczMCwiZXhwIjozMjM3MTE2MTgzNDYwfQ.nUrUFzyyP9POBTklc8ISXamJIz8D9vaUOIdS81_F9FY

Upvotes: 1

Views: 648

Answers (1)

jps
jps

Reputation: 22525

The decoded payload is:

{
...
  "iat": 1618556291730,
  "expiry": 1618559891730,
  "exp": 3237116183460
}

There are two things wrong:

  1. The format of the timestamps is wrong, because it's supposed to be in seconds (10 digit number) instead of milliseconds (13 digits) (see NumericDate in RFC7519).

  2. The the expiration time is (aside from the factor 1000) twice as high as expected.

The reason for that is a wrong calculation of the expiresIn parameter in you call to jwt.sign. The parameter is supposed to be a timesspan, e.g. { expiresIn: 60 * 60 } or { expiresIn: "1h" } for one hour, instead of a timestamp. The sign function will then add the timespan from the parameter to the current time to calculate the correct exp.

Upvotes: 2

Related Questions