Can I ask some novice questions here? For example:
I would like to configure oauth2 for my application, trying to follow docs on https://github.com/weavejester/ring-oauth2
So far I managed to understand that:
• this middleware needs to be placed after biff/wrap-session so it can store & verify the state code security check
• this middleware needs to be placed after wrap-params middleware to be able to read & compare GET parameters
But my limited experience with Clojure development is not enough yet to understand the best placement & middleware layout
After some experimenting, this seems to work:
(defn wrap-base-defaults [handler]
(-> handler
(wrap-oauth2 (oauth-config))
wrap-params
biff/wrap-session
muuntaja/wrap-params
biff/wrap-https-scheme
biff/wrap-resource
biff/wrap-internal-error
biff/wrap-ssl
biff/wrap-log-requests
))
but I have some doubtsbtw I also need to pass config data in my (oauth-config) function. this is unresolved yet (hardcoded for the testing time, but needs to be read from aero-config)
If it needs to run after wrap-session and wrap-params, you could insert it into wrap-site-defaults , like:
(defn wrap-site-defaults [handler]
(-> handler
biff/wrap-render-rum
biff/wrap-anti-forgery-websockets
csrf/wrap-anti-forgery
(wrap-oauth2 (oauth-config))
biff/wrap-session
muuntaja/wrap-params
muuntaja/wrap-format
(rd/wrap-defaults (-> rd/site-defaults
(assoc-in [:security :anti-forgery] false)
(assoc-in [:responses :absolute-redirects] true)
(assoc :session false)
(assoc :static false)))))
(note that since we're composing the middleware with ->, middleware that comes earlier in the chain runs last)
The downside of the code snippet you posted (moving wrap-session etc into wrap-base-defaults ) is that wrap-base-defaults gets used for both :routes and :api-routes in your Biff modules. If you ever start using :api-routes , you probably won't want to have it use wrap-session.
> btw I also need to pass config data in my (oauth-config) function. this is unresolved yet (hardcoded for the testing time, but needs to be read from aero-config)
The way to do this in Biff is somewhat peculiar: you'll need to make a wrapper middleware that doesn't need any config at "wrap" time, but on each request, it'll take the config from the incoming request / ctx and then pass it to the original oauth2 middleware:
(defn my-wrap-oauth2 [base-handler]
(fn [ctx]
(let [config (get-oauth-config ctx)
handler (wrap-oauth2 base-handler config)]
(handler ctx))))
I've set things up this way so that the middleware chain can be constructed/updated at the repl without having to refresh the whole system, i.e. just hit save and everything's up to date. The biff/wrap-session middleware does the same thing; it's mostly just a wrapper like the one above: https://github.com/jacobobryant/biff/blob/94eb24d96b0592399f264e1ee2ffeab186f46c78/src/com/biffweb/impl/middleware.clj#L115