Skip to content

Instantly share code, notes, and snippets.

@jacobemcken
Last active January 15, 2024 16:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jacobemcken/1c1d6caac8277b5e53fd1b2cec8552e3 to your computer and use it in GitHub Desktop.
Save jacobemcken/1c1d6caac8277b5e53fd1b2cec8552e3 to your computer and use it in GitHub Desktop.
Generate dummy JWT using ClojureScript in browser
(ns jwt
"Generate JTW using ClojureScript in browser.
**WARNING** Never store signing key / secret client side (in browser).
It isn't safe.
Play around with different tokens scenarios in a local environment,
without round-tripping 3. party services like Auth0 for every combination.
Implementation reference: https://jwt.io/introduction
Decode tokens in browser: https://jwt.io/"
(:require [clojure.string :as str]
[goog.crypt :as crypt]
[goog.crypt.base64 :as base64])
(:import [goog.crypt Hmac Sha256]))
(def hasher
(Sha256.))
(defn sign
[message secret]
(let [hmacer (Hmac. hasher (crypt/stringToByteArray secret))]
(.getHmac hmacer (crypt/stringToByteArray message))))
(defn clj->json
[m]
(.stringify js/JSON (clj->js m)))
(defn unsigned-token
[header payload]
(->> [header payload]
(map (comp #(base64/encodeString % base64/Alphabet.WEBSAFE_NO_PADDING) clj->json))
(str/join ".")))
(defn get-jwt
([payload secret]
(get-jwt payload secret {}))
([payload secret extra-headers]
(let [header (assoc extra-headers
"alg" "HS256"
"typ" "JWT")
token-base (unsigned-token header payload)
signature (sign token-base secret)]
(str token-base "." (base64/encodeByteArray
(js/Uint8Array. signature)
base64/Alphabet.WEBSAFE_NO_PADDING)))))
(comment
(println (get-jwt {"sub" "1234567890"
"name" "John Doe"
"iat" 1516239022}
"your-256-bit-secret"))
)
@jacobemcken
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment