jwt icon indicating copy to clipboard operation
jwt copied to clipboard

feat!: add support for type parameter

Open costela opened this issue 2 years ago • 10 comments

This PR introduces the type parameters to the API, allowing token claims to be accessed directly using their concrete types, without type assertions.

The change bumps the minimal go version to 1.18.

It also:

  • remove the claims parameter from all methods; replaced by the type
  • adds a jwt.NewParserFor generic initializer (keeping the jwt.NewParser as a jwt.MapClaims variant)
  • removes Parser.ParseWithClaims (claims can be derived from the parser)
  • removes request.ParseRequestWithClaims (requiring explicit typing)

:warning: this is currently targeted against the v5 branch, but should probably be rebased on a new v6 branch if v5 gets released without it.

Benchmarks
goos: linux
goarch: amd64
pkg: github.com/golang-jwt/jwt/v5
cpu: 12th Gen Intel(R) Core(TM) i7-1260P
                                        │  v5.bench   │              v6.bench              │
                                        │   sec/op    │   sec/op     vs base               │
ParseUnverified/map_claims-16             2.657µ ± 4%   2.626µ ± 8%       ~ (p=0.481 n=10)
ParseUnverified/map_claims#01-16          3.042µ ± 4%   2.960µ ± 7%       ~ (p=0.353 n=10)
ParseUnverified/map_claims#02-16          3.101µ ± 6%   3.132µ ± 5%       ~ (p=0.684 n=10)
ParseUnverified/map_claims#03-16          3.441µ ± 7%   3.361µ ± 7%  -2.30% (p=0.050 n=10)
ParseUnverified/map_claims#04-16          2.834µ ± 6%   2.739µ ± 6%  -3.35% (p=0.007 n=10)
ParseUnverified/map_claims#05-16          2.864µ ± 5%   2.764µ ± 4%  -3.51% (p=0.004 n=10)
ParseUnverified/map_claims#06-16          2.860µ ± 5%   2.746µ ± 3%  -3.99% (p=0.000 n=10)
ParseUnverified/map_claims#07-16          2.882µ ± 3%   2.750µ ± 4%  -4.58% (p=0.001 n=10)
ParseUnverified/map_claims#08-16          2.894µ ± 3%   2.755µ ± 3%  -4.80% (p=0.001 n=10)
ParseUnverified/map_claims#09-16          2.844µ ± 7%   2.769µ ± 5%  -2.65% (p=0.043 n=10)
ParseUnverified/map_claims#10-16          2.863µ ± 6%   2.758µ ± 5%  -3.65% (p=0.005 n=10)
ParseUnverified/map_claims#11-16          2.891µ ± 6%   2.799µ ± 3%  -3.17% (p=0.001 n=10)
ParseUnverified/map_claims#12-16          2.887µ ± 6%   2.835µ ± 3%  -1.80% (p=0.029 n=10)
ParseUnverified/map_claims#13-16          3.132µ ± 3%   3.033µ ± 3%  -3.15% (p=0.001 n=10)
ParseUnverified/map_claims#14-16          3.147µ ± 7%   3.013µ ± 5%  -4.26% (p=0.005 n=10)
ParseUnverified/map_claims#15-16          3.489µ ± 7%   3.371µ ± 5%  -3.37% (p=0.035 n=10)
ParseUnverified/map_claims#16-16          3.131µ ± 6%   3.052µ ± 2%  -2.51% (p=0.012 n=10)
ParseUnverified/registered_claims-16      2.965µ ± 6%   2.913µ ± 7%       ~ (p=0.171 n=10)
ParseUnverified/registered_claims#01-16   2.935µ ± 6%   2.909µ ± 4%       ~ (p=0.306 n=10)
ParseUnverified/registered_claims#02-16   3.285µ ± 6%   3.166µ ± 6%  -3.62% (p=0.005 n=10)
ParseUnverified/registered_claims#03-16   2.832µ ± 5%   2.739µ ± 7%  -3.27% (p=0.015 n=10)
ParseUnverified/registered_claims#04-16   3.275µ ± 5%   3.127µ ± 4%  -4.52% (p=0.003 n=10)
ParseUnverified/registered_claims#05-16   3.012µ ± 5%   2.894µ ± 5%  -3.90% (p=0.035 n=10)
ParseUnverified/registered_claims#06-16   3.151µ ± 5%   3.016µ ± 4%       ~ (p=0.052 n=10)
geomean                                   3.010µ        2.920µ       -3.02%

                                        │   v5.bench   │              v6.bench               │
                                        │     B/op     │     B/op      vs base               │
ParseUnverified/map_claims-16             2.141Ki ± 0%   2.117Ki ± 0%  -1.09% (p=0.000 n=10)
ParseUnverified/map_claims#01-16          2.273Ki ± 0%   2.250Ki ± 0%  -1.03% (p=0.000 n=10)
ParseUnverified/map_claims#02-16          2.272Ki ± 0%   2.249Ki ± 0%  -1.03% (p=0.000 n=10)
ParseUnverified/map_claims#03-16          2.374Ki ± 0%   2.351Ki ± 0%  -0.99% (p=0.000 n=10)
ParseUnverified/map_claims#04-16          2.141Ki ± 0%   2.117Ki ± 0%  -1.09% (p=0.000 n=10)
ParseUnverified/map_claims#05-16          2.141Ki ± 0%   2.117Ki ± 0%  -1.09% (p=0.000 n=10)
ParseUnverified/map_claims#06-16          2.141Ki ± 0%   2.117Ki ± 0%  -1.09% (p=0.000 n=10)
ParseUnverified/map_claims#07-16          2.141Ki ± 0%   2.117Ki ± 0%  -1.09% (p=0.000 n=10)
ParseUnverified/map_claims#08-16          2.141Ki ± 0%   2.117Ki ± 0%  -1.09% (p=0.000 n=10)
ParseUnverified/map_claims#09-16          2.141Ki ± 0%   2.117Ki ± 0%  -1.09% (p=0.000 n=10)
ParseUnverified/map_claims#10-16          2.141Ki ± 0%   2.117Ki ± 0%  -1.09% (p=0.000 n=10)
ParseUnverified/map_claims#11-16          2.141Ki ± 0%   2.117Ki ± 0%  -1.09% (p=0.000 n=10)
ParseUnverified/map_claims#12-16          2.141Ki ± 0%   2.117Ki ± 0%  -1.09% (p=0.000 n=10)
ParseUnverified/map_claims#13-16          2.273Ki ± 0%   2.250Ki ± 0%  -1.03% (p=0.000 n=10)
ParseUnverified/map_claims#14-16          2.273Ki ± 0%   2.250Ki ± 0%  -1.03% (p=0.000 n=10)
ParseUnverified/map_claims#15-16          2.375Ki ± 0%   2.352Ki ± 0%  -0.99% (p=0.000 n=10)
ParseUnverified/map_claims#16-16          2.273Ki ± 0%   2.250Ki ± 0%  -1.03% (p=0.000 n=10)
ParseUnverified/registered_claims-16      2.163Ki ± 0%   2.140Ki ± 0%  -1.08% (p=0.000 n=10)
ParseUnverified/registered_claims#01-16   2.211Ki ± 0%   2.188Ki ± 0%  -1.06% (p=0.000 n=10)
ParseUnverified/registered_claims#02-16   2.273Ki ± 0%   2.250Ki ± 0%  -1.03% (p=0.000 n=10)
ParseUnverified/registered_claims#03-16   2.140Ki ± 0%   2.116Ki ± 0%  -1.10% (p=0.000 n=10)
ParseUnverified/registered_claims#04-16   2.266Ki ± 0%   2.242Ki ± 0%  -1.03% (p=0.000 n=10)
ParseUnverified/registered_claims#05-16   2.156Ki ± 0%   2.133Ki ± 0%  -1.09% (p=0.000 n=10)
ParseUnverified/registered_claims#06-16   2.156Ki ± 0%   2.133Ki ± 0%  -1.09% (p=0.000 n=10)
geomean                                   2.202Ki        2.179Ki       -1.06%

                                        │  v5.bench  │             v6.bench              │
                                        │ allocs/op  │ allocs/op   vs base               │
ParseUnverified/map_claims-16             35.00 ± 0%   33.00 ± 0%  -5.71% (p=0.000 n=10)
ParseUnverified/map_claims#01-16          41.00 ± 0%   39.00 ± 0%  -4.88% (p=0.000 n=10)
ParseUnverified/map_claims#02-16          41.00 ± 0%   39.00 ± 0%  -4.88% (p=0.000 n=10)
ParseUnverified/map_claims#03-16          46.00 ± 0%   44.00 ± 0%  -4.35% (p=0.000 n=10)
ParseUnverified/map_claims#04-16          35.00 ± 0%   33.00 ± 0%  -5.71% (p=0.000 n=10)
ParseUnverified/map_claims#05-16          35.00 ± 0%   33.00 ± 0%  -5.71% (p=0.000 n=10)
ParseUnverified/map_claims#06-16          35.00 ± 0%   33.00 ± 0%  -5.71% (p=0.000 n=10)
ParseUnverified/map_claims#07-16          35.00 ± 0%   33.00 ± 0%  -5.71% (p=0.000 n=10)
ParseUnverified/map_claims#08-16          35.00 ± 0%   33.00 ± 0%  -5.71% (p=0.000 n=10)
ParseUnverified/map_claims#09-16          35.00 ± 0%   33.00 ± 0%  -5.71% (p=0.000 n=10)
ParseUnverified/map_claims#10-16          35.00 ± 0%   33.00 ± 0%  -5.71% (p=0.000 n=10)
ParseUnverified/map_claims#11-16          35.00 ± 0%   33.00 ± 0%  -5.71% (p=0.000 n=10)
ParseUnverified/map_claims#12-16          35.00 ± 0%   33.00 ± 0%  -5.71% (p=0.000 n=10)
ParseUnverified/map_claims#13-16          41.00 ± 0%   39.00 ± 0%  -4.88% (p=0.000 n=10)
ParseUnverified/map_claims#14-16          41.00 ± 0%   39.00 ± 0%  -4.88% (p=0.000 n=10)
ParseUnverified/map_claims#15-16          46.00 ± 0%   44.00 ± 0%  -4.35% (p=0.000 n=10)
ParseUnverified/map_claims#16-16          41.00 ± 0%   39.00 ± 0%  -4.88% (p=0.000 n=10)
ParseUnverified/registered_claims-16      35.00 ± 0%   33.00 ± 0%  -5.71% (p=0.000 n=10)
ParseUnverified/registered_claims#01-16   39.00 ± 0%   37.00 ± 0%  -5.13% (p=0.000 n=10)
ParseUnverified/registered_claims#02-16   42.00 ± 0%   40.00 ± 0%  -4.76% (p=0.000 n=10)
ParseUnverified/registered_claims#03-16   34.00 ± 0%   32.00 ± 0%  -5.88% (p=0.000 n=10)
ParseUnverified/registered_claims#04-16   41.00 ± 0%   39.00 ± 0%  -4.88% (p=0.000 n=10)
ParseUnverified/registered_claims#05-16   35.00 ± 0%   33.00 ± 0%  -5.71% (p=0.000 n=10)
ParseUnverified/registered_claims#06-16   35.00 ± 0%   33.00 ± 0%  -5.71% (p=0.000 n=10)
geomean                                   37.66        35.65       -5.34%

costela avatar Feb 18 '23 17:02 costela

I like the idea of having a seperate NewParserFor that is generic and keeping the other one as MapClaims or just the Claims interface. Another idea that I had is basically having two types: one as generic and a second one without genetics as an alias to replace the existing Keyfunc/token type. This could even make it almost backwards compatible with some twisting. Or at least not break existing code too much for people who do not want/need generics.

Something like:

type TokenFor[T Claims] struct{ /*… */ }
type Token = TokenFor[Claims]

The „new“ Token should the pretty much behave the same as the old one.

oxisto avatar Feb 18 '23 18:02 oxisto

@oxisto yes, that's a good point with the type aliases!

I'll rebase and see if we can still make this backward compatible. Sounds good?

costela avatar Feb 22 '23 13:02 costela

@oxisto yes, that's a good point with the type aliases!

I'll rebase and see if we can still make this backward compatible. Sounds good?

Sure!

oxisto avatar Feb 22 '23 14:02 oxisto

Rebase done :heavy_check_mark:

I don't think we can achieve 100% backward-compatibility since jwt.Parse returned a token with a jwt.Claims, but used jwt.MapClaims internally. But IMHO the "new" API feels a bit cleaner. WDYT?

The other breaking change is more of an opinion: I personally always found the passing-in of claims a bit weird. But of course we can just put it back in, if the general opinion wants it.

costela avatar Feb 25 '23 20:02 costela

@oxisto did you (or any other maintainer) have a chance to look at this? :innocent:

costela avatar Mar 16 '23 21:03 costela

This is a nice feature, it would be great if it could be merged

hantonelli avatar Dec 20 '23 13:12 hantonelli

Any updates on when this will be merged?

hantonelli avatar Jan 24 '24 09:01 hantonelli

@hantonelli sorry, this totally got lost in the day-to-day work.

I'll try to rebase and address the points above :crossed_fingers:

costela avatar Jan 28 '24 20:01 costela

This is a nice feature, it would be great if it could be merged

Outside of generics, does this PR have a feature that's missing from the current /v5 library?

mfridman avatar Jan 28 '24 20:01 mfridman