Export IntDate
ocramz opened this issue · 4 comments
Bump. It's not immediately clear how to construct a JwtClaims
... it seems like I have to do
toIntDate posixTime =
case Aeson.fromJSON $ Aeson.toJSON posixTime of
Aeson.Success d -> d
Aeson.Error s -> error $ "Could not roundtrip POSIX time (" ++ show posixTime ++ "): " ++ s
On the topic of improving the API, it'd be great to have the following:
- An
emptyJwtClaims
/mempty
implementation forJwtClaims
- An
Exception JwtError
instance
Why can't you just create it directly? Admittedly I haven't looked at any of this for a while but I have code that does just that in another project and last time I checked it compiled fine.
JwtClaims
was originally created as a dirty way of accessing the standard token claims before verifying the token in cases where that was necessary (see this function). It wasn't really intended to be encoded as the full token content.
oh interesting. IntDate doesn't show up in the haddocks, so I didn't think it was available. Maybe Jose.Jwt can explicitly list everything reexported instead of reexporting the Jose.Types internal module?
If JwtClaims wasn't intended to encode the standard token claims, what is the intended way? The most common usage of JWTs is to transmit auth claims, and IMO it doesnt make sense for an auth application to decode a token that it didnt generate/encode in the first place.
It would also be cool to expose an extraClaims field like what jwt
does:
https://hackage.haskell.org/package/jwt-0.11.0/docs/Web-JWT.html#t:JWTClaimsSet
IntDate
was only created to make encoding and decoding easier without running into orphan instance issues with FromJSON
and ToJSON
. It was originally an implementation detail and I strongly dislike the name and would like to rename it to something like PosixSeconds
before doing a 1.0 release. There's nothing to stop you using it for now though. It could easily be deprecated and phased out later.
If JwtClaims wasn't intended to encode the standard token claims, what is the intended way?
To quote the Readme/doc:
Technically, the content of a JWT should be JSON (unless it's a nested JWT), but this library doesn't care - it only requires a bytestring. The application should verify that the content is valid. Exactly what that means will depend on what you are using JWTs for.
So there is no intended way other than to create the content as you wish and passing a bytestring to the library. In many cases this will be by creating a type and its corresponding aeson typeclass implementations but it doesn't have to be.
IMO it doesnt make sense for an auth application to decode a token that it didn't generate/encode in the first place
This is clearly not the case. If an app is only consuming tokens that it has signed itself, then there's not much need for a specification, particularly one which supports so many asymmetric cryptography algorithms and places such an emphasis on checking the aud
claim. The first line of the spec also says that it "represents claims to be transferred between two parties". The ID tokens used in OpenID Connect are just one example of this and there are at least two others in the same spec that I can think of where the party which creates the token is not the one who verifies it (request object signing and client assertion authentication). JWTs are also often used as access tokens (https://oauth.net/2/jwt-access-tokens/) where the recipient is the resource server, which is decoding a token issued by the authorization server.
However, who is signing/verifying the token is irrelevant from the library's perspective. It can encode and decode tokens but doesn't make any attempt to interpret or validate the claims in them. I considered the possibility of adding an "extra claims" map in the past but trying to cater for all the different use cases seemed like a bad idea. The data in the claims varies a lot and is often a superset of the standard claims where some or all fields are required, whereas in the JwtClaims
data type they are all Maybe
by necessity. So I would recommend coding a specific type for your use case and you can then also build validation around that (for example with a custom newtype for the aud
claim).