-
Notifications
You must be signed in to change notification settings - Fork 356
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix!: NumericDate parsing conformance #9
Conversation
Looking at the CI... this is interesting, it seems that this fails for very old Go versions (which might be ok). I think we still have not quite 100% decided on which minimum Go version we want to support. Do you know what the minimum version for your patch would be? |
@oxisto I guess we'll see how does the change affect this. From the github actions we already know it works on newer versions but just for the sake of verifying I added those versions to the travis build |
NotBefore int64 `json:"nbf,omitempty"` | ||
Subject string `json:"sub,omitempty"` | ||
Audience string `json:"aud,omitempty"` | ||
ExpiresAt float64 `json:"exp,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for submitting a PR.
I believe one of the goals here is to maintain backwards compatibility with the upstream repo. I.e., make it a drop-in replacement.
Instead of changing the StandardClaims
struct, would it suffice to add a new struct with an explanation and/or a deprecation notice?
New users would be pushed towards the "correct struct", while existing users are unaffected but have the option to update their implementations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be one way to go. I'm feeling very urged to fix the current one but as we want to maintain the drop-in contract in order to ease the transition from the already deprecated and stale package we'll probably have to work around it this way until a new release is made in this one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As you wish, but the current implementation is not valid according to the spec and fails hard in the wild (basically when interacting with any PHP project, because Lcobucci's lib is the most popular in this ecosystem).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd love to see this fixed as well. Although I think it's an easier migration story for users:
golang-jwt/jwt v1.x.x is backwards-compatible with dgrijalva/jwt-go (despite the incorrect implementation you pointed out)
and then we could consider further improvements for those already on /v1 that breaks compatibility with a /v2 release
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd love to see this fixed as well. Although I think it's an easier migration story for users:
golang-jwt/jwt v1.x.x is backwards-compatible with dgrijalva/jwt-go (despite the incorrect implementation you pointed out)
and then we could consider further improvements for those already on /v1 that breaks compatibility with a /v2 release
I fear, that this won't be completely possible anyway, because the cleanest fix to #6 (which we agreed on fixing before our first "release") is to adjust the claims struct, changing Audience
from string
to []string
. We might as well correct the float/int issue as well before releasing v1.x.x
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hehe, these are the trickiest tradeoffs. The breaking change is justified from a security and spec perspective, but keeping StandardClaims
as-is maintains backwards-compatibility. The latter is something most Go folks have come to appreciate. Just want to make sure if we do break StandardClaims
its worth it.
What are your thoughts w.r.t adding a new struct RegisteredClaims
while keeping StandardClaims
unchanged with a deprecation notice and comment suggesting against its use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will play around with this idea over the weekend. With that in mind I would then also probably choose to make the audience field directly a time Field instead of an into or float and have appropriate MarshalJSON functions that take care of the conversion. This feels more naturally and idiomatic to me than assigning the expiry in a float value.
This got weird quick So, here's a complete test matrix and it turns out it breaks the tests as late as go 1.12 with the same errors:
But there are no noteworthy changes in 1.13 that may seem related to this: https://golang.org/doc/go1.13#time |
Aside from this thread, this PR would push the minimum go requirement to 1.13. Not that I disagree since the project is already temporarily (?) defined as a 1.14 module but it is something to take into account in regards to backwards compatibility If I get some spare time I'll try to dig deeper into this issue to see if I can find the cause |
@@ -150,7 +151,7 @@ func createToken(user string) (string, error) { | |||
&jwt.StandardClaims{ | |||
// set the expire time | |||
// see http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-20#section-4.1.4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While we are at: Changing this reference to https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4 would be appropriate as well. That is btw the source of the "wrong" implementation. When the library was initially started, RFC7519 did not exist - only its drafts. The referenced draft actually stated that iat
, exp
and so on must be a IntDate
, which did not include the float part. It got then later changed to a NumericDate
format in draft version 26, which - as you correctly pointed out - included also float representations.
@dunglas As you might have seen, I have prepared a PR (#15) that addresses several issues with regards to the RFC conformance. Would you mind taking a look there, to check if this would suit your particular needs? My current plan is to include this in a |
Closing in favor of #15. |
The current implementation of the standard claims parser is invalid. It doesn't allow
NumericDate
value to be floats, while it's explicitly allowed by the RFC:(Emphasis mine).
This is annoying because popular libraries generate tokens containing floats in the
exp
,iat
andnbf
fields. For instance, it's the case oflcobucci/jwt
, one of the most popular JWT library written in PHP.This PR fixes this, and also allows comparing fractions of seconds.
This is a BC break, so it should be merged in the 4.0 version.
Also, as this library is a core dependency of my Mercure project, if you need help for the maintenance of this library, I'll be glad to participate!
Closes dunglas/mercure#404 and form3tech-oss/jwt-go#11.