Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

clojure - How to generate JWT exp claim with java-time?

Most examples for JWT token use clj-time which is now deprecated in favor of native java.time. I'm trying to use java-time along with buddy to sign/verify tokens but I'm stuck trying to pass the exp claim to my token. Here's an example of what I have:

(ns test-app.test-ns
  (:require
   [buddy.sign.jwt :as jwt]
   [buddy.auth.backends.token :as bat]
   [java-time :as t]))

(def secret "myfishysecret")

(def auth-backend (bat/jws-backend {:secret secret
                                    :options {:alg :hs512}}))
(def token (jwt/sign {:user "slacker"
                      :exp (t/plus (t/local-date-time) (t/seconds 60))
                      } secret {:alg :hs512}))

When tyring to test if I can unsign the token

(jwt/unsign token secret {:alg :hs512})

I get the following error:

Execution error (JsonGenerationException) at cheshire.generate/generate (generate.clj:152). Cannot JSON encode object of class: class java.time.LocalDateTime: 2021-01-22T12:37:52.206456

So, I tried to pass the same by encapsulating the call to (t/plus ...) inside a (str) but then I get this error:

class java.lang.String cannot be cast to class java.lang.Number
(java.lang.String and java.lang.Number are in module java.base of loader 'bootstrap')

So, I'm stuck since I don't really know how to generate a valid exp number value using java-time (according to this question, format should be in seconds since the epoch). Older examples using clj-time just passed the exp claim value as

(clj-time.core/plus (clj-time.core/now) (clj-time.core/seconds 3600))

Any help is highly appreciated.

EDIT: Alan Thompson's answer works perfectly, for what's worth this would be the equivalent using the java-time wrapper:

(t/plus (t/instant) (t/seconds 60))
question from:https://stackoverflow.com/questions/65851030/how-to-generate-jwt-exp-claim-with-java-time

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here are 2 ways to do it:

  (let [now+60          (-> (Instant/now)
                          (.plusSeconds 60))
        now+60-unixsecs (.getEpochSecond now+60)]

    (jwt/sign {:user "slacker" :exp now+60         } secret {:alg :hs512})
    (jwt/sign {:user "slacker" :exp now+60-unixsecs} secret {:alg :hs512}))

and we have the now results:

now+60            => <#java.time.Instant #object[java.time.Instant 0x7ce0054c "2021-01-22T19:04:51.905586442Z"]>
now+60-unixsecs   => <#java.lang.Long 1611342291>

So you have your choice of methods. It appears that buddy knows how to convert from a java.time.Instant, so going all the way to unix-seconds is unnecessary.

You may also be interested in this library of helper and convenience functions for working with java.time.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...