diff --git a/README.md b/README.md index c9b4f29..c20557a 100644 --- a/README.md +++ b/README.md @@ -30,21 +30,21 @@ A Clojure library for JSON Web Token(JWT) [draft-ietf-oauth-json-web-token-19](h (def claim {:iss "foo" :exp (plus (now) (days 1)) - :nbf (now)}) + :iat (now)}) (def rsa-prv-key (private-key "rsa/private.key" "pass phrase")) (def ec-prv-key (private-key "ec/private.key")) -; plain JWT +;; plain JWT (-> claim jwt to-str) -; HMAC256 signed JWT +;; HMAC256 signed JWT (-> claim jwt (sign :HS256 "secret") to-str) -; RSA256 signed JWT +;; RSA256 signed JWT (-> claim jwt (sign :RS256 rsa-prv-key) to-str) -; ECDSA256 signed JWT +;; ECDSA256 signed JWT (-> claim jwt (sign :ES256 ec-prv-key) to-str) ``` @@ -60,22 +60,26 @@ A Clojure library for JSON Web Token(JWT) [draft-ietf-oauth-json-web-token-19](h (def claim {:iss "foo" :exp (plus (now) (days 1)) - :nbf (now)}) + :iat (now)}) (def rsa-prv-key (private-key "rsa/private.key" "pass phrase")) (def rsa-pub-key (public-key "rsa/public.key")) (def ec-prv-key (private-key "ec/private.key")) (def ec-pub-key (public-key "ec/public.key")) +;; verify plain JWT (let [token (-> claim jwt to-str)] (-> token str->jwt verify)) +;; verify HMAC256 signed JWT (let [token (-> claim jwt (sign :HS256 "secret") to-str)] (-> token str->jwt (verify "secret"))) +;; verify RSA256 signed JWT (let [token (-> claim jwt (sign :RS256 rsa-prv-key) to-str)] (-> token str->jwt (verify rsa-pub-key))) +;; verify ECDSA256 signed JWT (let [token (-> claim jwt (sign :ES256 ec-prv-key) to-str)] (-> token str->jwt (verify ec-pub-key))) ``` diff --git a/project.clj b/project.clj index 7bf2915..910cae2 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject clj-jwt "0.0.5" +(defproject clj-jwt "0.0.6" :description "Clojure library for JSON Web Token(JWT)" :url "https://github.com/liquidz/clj-jwt" :license {:name "Eclipse Public License" diff --git a/src/clj_jwt/core.clj b/src/clj_jwt/core.clj index 68ec02b..11233f9 100644 --- a/src/clj_jwt/core.clj +++ b/src/clj_jwt/core.clj @@ -2,7 +2,7 @@ (:require [clj-jwt.base64 :refer [url-safe-encode-str url-safe-decode-str]] [clj-jwt.sign :refer [get-signature-fn get-verify-fn supported-algorithm?]] - [clj-time.coerce :refer [to-long]] + [clj-jwt.intdate :refer [joda-time->intdate]] [clojure.data.json :as json] [clojure.string :as str])) @@ -10,8 +10,6 @@ (def ^:private map->encoded-json (comp url-safe-encode-str json/write-str)) (def ^:private encoded-json->map (comp #(json/read-str % :key-fn keyword) url-safe-decode-str)) (defn- update-map [m k f] (if (contains? m k) (update-in m [k] f) m)) -(defn- joda-time? [x] (= org.joda.time.DateTime (type x))) -(defn- to-intdate [d] {:pre [(joda-time? d)]} (int (/ (to-long d) 1000))) (defrecord JWT [header claims signature]) @@ -28,7 +26,7 @@ (extend-protocol JsonWebToken JWT (init [this claims] - (let [claims (reduce #(update-map % %2 to-intdate) claims [:exp :nbf :iat])] + (let [claims (reduce #(update-map % %2 joda-time->intdate) claims [:exp :nbf :iat])] (assoc this :header {:alg "none" :typ "JWT"} :claims claims :signature ""))) (encoded-header [this] diff --git a/src/clj_jwt/intdate.clj b/src/clj_jwt/intdate.clj new file mode 100644 index 0000000..ac2b32f --- /dev/null +++ b/src/clj_jwt/intdate.clj @@ -0,0 +1,16 @@ +(ns clj-jwt.intdate + (:require + [clj-time.coerce :refer [to-long from-long]])) + +(defn- joda-time? [x] (= org.joda.time.DateTime (type x))) + +(defn joda-time->intdate + [d] + {:pre [(joda-time? d)]} + (int (/ (to-long d) 1000))) + + +(defn intdate->joda-time + [i] + {:pre [(integer? i) (pos? i)]} + (from-long (* i 1000))) diff --git a/test/clj_jwt/intdate_test.clj b/test/clj_jwt/intdate_test.clj new file mode 100644 index 0000000..06b9127 --- /dev/null +++ b/test/clj_jwt/intdate_test.clj @@ -0,0 +1,17 @@ +(ns clj-jwt.intdate-test + (:require + [clj-jwt.intdate :refer :all] + [clj-time.core :refer [date-time]] + [midje.sweet :refer :all])) + +(fact "joda-time->intdate should work fine." + (let [d (date-time 2000 1 2 3 4 5)] + (joda-time->intdate d) => 946782245 + (joda-time->intdate nil) => (throws AssertionError))) + +(fact "intdate->joda-time should work fine." + (let [d (date-time 2000 1 2 3 4 5) + i (joda-time->intdate d)] + (intdate->joda-time i) => d + (intdate->joda-time nil) => (throws AssertionError))) +