如何用 java 时间生成 JWT exp 声明?
How to generate JWT exp claim with java-time?
JWT 令牌的大多数示例使用 clj-time which is now deprecated in favor of native java.time. I'm trying to use java-time along with buddy 到 sign/verify 令牌,但我一直试图将 exp 声明传递给我的令牌。这是我所拥有的示例:
(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}))
当我尝试测试是否可以取消标记令牌时
(jwt/unsign token secret {:alg :hs512})
我收到以下错误:
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
所以,我试图通过将对 (t/plus ...) 的调用封装在 (str) 中来传递它,但随后出现此错误:
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')
所以,我被卡住了,因为我真的不知道如何使用 java-time 生成有效的 exp 数值(根据 question, format should be in seconds since the epoch). Older examples using clj-time 刚刚传递的 exp 声明值作为
(clj-time.core/plus (clj-time.core/now) (clj-time.core/seconds 3600))
非常感谢任何帮助。
编辑:Alan Thompson 的回答非常有效,因为这与使用 java-time 包装器等效:
(t/plus (t/instant) (t/seconds 60))
这里有两种方法:
(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}))
我们得到 now
结果:
now+60 => <#java.time.Instant #object[java.time.Instant 0x7ce0054c "2021-01-22T19:04:51.905586442Z"]>
now+60-unixsecs => <#java.lang.Long 1611342291>
所以你可以选择方法。看来哥们知道如何从java.time.Instant
转换,所以一直到unix-seconds是不必要的。
您可能也对此 library of helper and convenience functions 感兴趣,以便与 java.time
一起工作。
JWT 令牌的大多数示例使用 clj-time which is now deprecated in favor of native java.time. I'm trying to use java-time along with buddy 到 sign/verify 令牌,但我一直试图将 exp 声明传递给我的令牌。这是我所拥有的示例:
(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}))
当我尝试测试是否可以取消标记令牌时
(jwt/unsign token secret {:alg :hs512})
我收到以下错误:
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
所以,我试图通过将对 (t/plus ...) 的调用封装在 (str) 中来传递它,但随后出现此错误:
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')
所以,我被卡住了,因为我真的不知道如何使用 java-time 生成有效的 exp 数值(根据
(clj-time.core/plus (clj-time.core/now) (clj-time.core/seconds 3600))
非常感谢任何帮助。
编辑:Alan Thompson 的回答非常有效,因为这与使用 java-time 包装器等效:
(t/plus (t/instant) (t/seconds 60))
这里有两种方法:
(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}))
我们得到 now
结果:
now+60 => <#java.time.Instant #object[java.time.Instant 0x7ce0054c "2021-01-22T19:04:51.905586442Z"]>
now+60-unixsecs => <#java.lang.Long 1611342291>
所以你可以选择方法。看来哥们知道如何从java.time.Instant
转换,所以一直到unix-seconds是不必要的。
您可能也对此 library of helper and convenience functions 感兴趣,以便与 java.time
一起工作。