Liking cljdoc? Tell your friends :D

funcade

creates, manages and refreshes oauth 2.0 jwt tokens

<! release <! clojars

make them tokens

=> (require '[funcade.core :as f])

=> (def conf {:client-id "planet-earth"
              :scope "solar-system"
              :access-token-url "https://milky-way-galaxy/token.oauth2"
              :client-secret "super-hexidecimal-secret"})

optional config properties:

namedefaultdescription
:token-headers{:Content-Type "application/x-www-form-urlencoded"}headers passed to aquire the token
:grant-type"client_credentials"oauth 2.0 grant type
:refresh-percent10when less than % of time between expires-at and issued-at remains, refreshes the token
=> (def token-repo (f/wake-token-master :serpens conf))

=> (f/current-token token-repo)
;; "eyJhbGci...dc22w"
user=> (f/stop token-repo)
true

group many sources

=> (def sources {:mars {:client-id "..."
                        :client-secret "..."
                        :access-token-url "..."
                        :scope "..."}
                 :asgard {:client-id "..."
                          :client-secret "..."
                          :access-token-url "..."
                          :scope "..."}})

=> (def jwt (f/wake-token-masters sources))

creates two token masters:

=> jwt
;; {:mars #object[funcade.core.TokenMaster"],
;;  :asgard #object[funcade.core.TokenMaster"]}

=> (-> jwt :mars f/current-token)
;; "eyJhbGci...dc22w"

=> (-> jwt :asgard f/current-token)
;; "eyJhbRkv...id95p"

using middleware

funcade has middleware and helpers to use auth requests protected behind JWT tokens with various scopes.

=> (require '[reitit.ring :as ring])
=> (require '[funcade.middleware.reitit :as fun])

=> (def config {:jwk {:uri "https://milky-way-galaxy/ext/jwtsigningcert/jwks"})

=> (def app
      (ring/ring-handler
        (ring/router
          ["/ping" {:get {:scope :my-scope
                          :handler (fn [_]
                                     {:status 200
                                      :body "success"})}}]
          {:data {:middleware [(fun/wrap-jwt-authentication config})
                               fun/scope-middleware]}})))

valid request:

=> (def token "eyJhbGci...dc22w")

=> (app {:request-method :get :uri "/ping" :headers {:authorization (str "Bearer " token)}})
;; {:status 200, :body "success"}

invalid/missing token:

=> (app {:request-method :get :uri "/ping"}})
;; {:status 401, :body {:error "invalid authorization header", :message "access to /ping is not authorized"}}

invalid scope:

=> (def token "eyJhbGci...dc22w")

=> (app {:request-method :get :uri "/ping" :headers {:authorization (str "Bearer " token)}})
;; {:status 401, :body {:message "missing required scope", :required :my-scope, :scopes (:not-my-scope)}}

license

copyright © 2020 shvetsm

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

Can you improve this documentation? These fine people already did:
anatoly, Mark Shvets, Anatoly & James Kent
Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close