go-chi / jwtauth

JWT authentication middleware for Go HTTP services
MIT License
541 stars 91 forks source link

I seem to be having issues and errors with NBF #54

Closed adrianocr closed 3 years ago

adrianocr commented 3 years ago

The JWT look like this:

{
  "iss": "...",
  "dest": "...",
  "aud": "...",
  "sub": "...",
  "exp": 1609818402, //-> 01/05/2021 @ 3:46:42am (UTC)
  "nbf": 1609818342, //-> 01/05/2021 @ 3:45:42am (UTC)
  "iat": 1609818342, //-> 01/05/2021 @ 3:45:42am (UTC)
  "jti": "...",
  "sid": "..."
}

I dev apps for a service (Shopify) that lets you request a JWT from their servers, and then you can use that JWT to make authenticated calls to your backend (since the token is signed with your API secret, which both you and Shopify have on hand). My backend uses this JWT middleware to handle that part.

The issue I'm having is that it seems if I request a JWT and immediately use it to make a call to my backend (we're talking sub 50 milliseconds between getting the JWT and making a request to my backend), the JWT middleware returns the following error: token nbf validation failed

If I then use a setTimeout() function on my frontend to add a 750-1000ms delay after requesting the JWT, the issue does not happen. So it seems to me like there's something going on with the underlying library/implementation that causes the backend to think it hasn't reached the correct NBF time yet?

Not sure how I would go about resolving this other than manually adding delays before making calls to my backend. Suggestions?

pkieltyka commented 3 years ago

clocks are notoriously difficult to synchronize, I recommend to set nbf 1-3 minutes before current time when generating the token

adrianocr commented 3 years ago

@pkieltyka that's not a valid solution. I don't have access to Shopify's token generation so how am I supposed to set the NBF field to 1-3 mins back? If I were generating the token myself, sure, but I'm not.

Ideally this middleware should allow for specifying a "grace period" of sorts. Is that not feasible?

pkieltyka commented 3 years ago

I see. You can implement the grace period yourself in this instance, write a middleware handler to check nbf and sleep for few seconds if you need the buffer. This isn't a bug report, and my bandwidth is limited to offer further help

adrianocr commented 3 years ago

It seems to me like this actually is a bug, and not simply an implementation issue. If I try to manually get around the problem it still fails because the verifier seems to kick up a problem with the nbf field even before it gets to the authenticator function. Additionally I wanted to make sure so I tested it repeatedly and here you'll see time.Now().UTC() is in fact after the nbf time, yet it still fails:

2021/01/06 17:45:01 nbf: 2021-01-06 22:44:32 +0000 UTC, now: 2021-01-06 22:45:01 +0000 UTC 2021/01/06 17:45:05 nbf: 2021-01-06 22:44:32 +0000 UTC, now: 2021-01-06 22:45:05 +0000 UTC 2021/01/06 17:46:03 nbf: 2021-01-06 22:46:03 +0000 UTC, now: 2021-01-06 22:46:03 +0000 UTC

Those are all instances where the nbf check failed, yet the server time was after the nbf time. So what am I missing here?