3

Original code:

const token = jwt.sign({ _id: user._id }, process.env.JWT_SECRET, { expiresIn: '1d' });
        
res.cookie('token', token, { expiresIn: '1d' });

This worked. The token expired in exactly one day from its creation.

The change:

const token = jwt.sign({ _id: user._id }, process.env.JWT_SECRET, { expiresIn: '1m' });
        
res.cookie('token', token, { expiresIn: '1m' });

I signed out, restarted the server, but still no change! The token still set itself to expire in one day. I'm following a course and when the course instructor made this change in his code, it worked as expected. The token expired in one minute.

I even tried:

const token = jwt.sign({ _id: user._id }, process.env.JWT_SECRET, { expiresIn: '10' });
        
res.cookie('token', token, { expiresIn: '10' });

Expecting the token to expire in ten seconds or ten milliseconds (I'm not sure what the default unit is) but still the same result. The token still is set to expire in one day.

Is this a cache thing? I have almost zero knowledge on cache, what it is, and how it works, but it is hard for me to imagine that the explanation to this is within the regular bounds of NodeJS coding itself. It would be pretty straightforward if it was. There is no other "configuration" of the jwt module or of how my app handles cookies or tokens in the entire app.

I included the next.js tag because I am using this in a next.js application (although I'm doubtful that is relevant, I could be wrong of course).

Matthew Wolman
  • 645
  • 9
  • 18
  • I can't find any error in this code, can you just edit it with your method – BINFAS K Jul 24 '20 at 17:43
  • 1
    Have you tried to inspect cookies in your app? Is there a single cookie or multiple cookies? Which token is in the cookie? How the token looks like? What expiration date it shows when you unpack it manually on jwt.io? – Wiktor Zychla Jul 24 '20 at 17:52
  • @BINFASK there isn't any error in the code. That is why I'm confused. How could the token expiration time still be one day when I changed it to one minute or just 10? – Matthew Wolman Jul 24 '20 at 18:42
  • @WiktorZychla I've looked at the cookies and there is one cookie called token (as is expected) and this token has an expiration date of exactly one day after I sign in. This was to be expected with the `expiresIn: '1d'` code, but it still stays as one day even when I change it to `'1m'` or `'10'`. I haven't "unpacked it manually" with jwt.io. I've never done that before. The token is just a really long string of numbers and characters. – Matthew Wolman Jul 24 '20 at 18:44
  • Unpacking means copying this string to jwt.io to see what's inside. – Wiktor Zychla Jul 24 '20 at 18:56
  • Here it is pasted in the debugger: https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1ZWY4YmZlYjM2OTUxODM2NTgyZWQ4MGMiLCJpYXQiOjE1OTU2MTExNDksImV4cCI6MTU5NTYxMTE0OX0.8ZltjIjoFAnlpoylDGZXo1sdjFjqGIK8rhhgH02fDJ8 – Matthew Wolman Jul 24 '20 at 19:19
  • It has the MongoDB document id and an "iat" and "exp" key. I'm assuming "exp" means expiry but I don't know what "iat" means. Either way, the "exp" value pair is showing the same exact date as the "iat" value pair. I'm currently using `{ expiresIn: '10' }` which I'm now assuming is 10 milliseconds, so the expiry date, being only 10 ms later than the creation date, is showing to be the exact same as the creation date (because they don't show the millisecond value in the date). – Matthew Wolman Jul 24 '20 at 19:23
  • Okay I think I get what is going on but I still don't have a solution. I think the JWT token itself has the correct expiration time, but when sending it to the browser as a cookie, the cookie is staying with an expiration of one day. Some how, some where, I'm still setting the cookie expiration to be on day. It is just odd because the instructor has the exact same code and was able to implement the change with just the code shown. – Matthew Wolman Jul 24 '20 at 19:28
  • `iat` is "issued at". The int here is the unix timestamp format, it could be [validated online](https://www.epochconverter.com/). The iat and exp **should not** have the same value. Regardless of what cookie expiration is, if the cookie contains an expired token, the receiver should discard it. – Wiktor Zychla Jul 24 '20 at 20:38
  • 1
    Can you change expiresIn property to maxAge in the cookie part – gkrthk Jul 25 '20 at 14:03

1 Answers1

3

I figured it out. Not to fault anyone who commented with a potential solution because there was information missing that I did not realize was there.

This is a NextJS application and there is separate logic on the front end with setting this cookie's expiration date. This expiration date was set to a day and I was not changing it (I forgot it existed). Once I changed it, the change reflected in the browser.

I guess you can set an expiration date for the signed jwt that is separate from the cookie expiration date on the front end. It's redundant and not desirable. I'll have to look for a different long-term solution. I wouldn't find this to be good for real world applications as it makes it difficult to understand what is happening.

Earlier this morning, before I figured this out, the jwt expiration of 10 milliseconds finally started working, but only on the back end. I got a back end error saying my jwt session had expired, which was to be expected. The request made to the back end on my front end page failed because it wasn't authenticated, so I got the expected behavior, but not in the way I was expecting it.

EDIT: I believe I've found the crux of my confusion. The code below is the back end code that was intended to set the cookie in the response, but because we are using separate logic to set the cookie in the front end, I believe this code is not actually doing anything. I've looked over the front end code receives the signed jwt token and no where in there is the res.cookie being referenced. I believe this must have just been an extra line of code the instructor thought was necessary. I've run out of time today, but I'm going to attempt to run the app without this line of code and see if I get them same functionality.

res.cookie('token', token, { expiresIn: '1d' });

Regarding this:

I guess you can set an expiration date for the signed jwt that is separate from the cookie expiration date on the front end. It's redundant and not desirable. I'll have to look for a different long-term solution. I wouldn't find this to be good for real world applications as it makes it difficult to understand what is happening.

I've come to understand that this is an extra layer of security that is valuable to have. The issue was not with the jwt logic on the back end. The issue here is simply that I had extra logic setting up the cookie in the browser in two different places and adjusted the logic that was not being used by the app and browser.

Matthew Wolman
  • 645
  • 9
  • 18