I have some routes.
(defroutes some-routes
(GET "one" [] one)
(GET "two" [] two))
(defroutes other-routes
(GET "three" [] three)
(GET "four" [] four))
(defroutes more-routes
(GET "five" [] five)
(GET "six" [] six))
(def all-routes
(routes app-routes
(-> some-routes session/wrap-session my-interceptor)
(-> more-routes session/wrap-session my-other-interceptor)
other-routes))
I want to intercept the some-routes but not other-routes and perform a test based on the request (checking that a key exists in the session and some other stuff). I have more than one of these. my-other-interceptor does the same kind of thing but different.
So I start with this:
(defn my-interceptor [handler]
(fn [request]
(prn (-> request :session :thing-key))
(let [thing (-> request :session :thing-key-id)]
(if (nil? thing)
(-> (response "Not authenticated"))
(handler request)))))
This will allow access to the handler if :thing-key is set in the session.
Unfortunately this doesn't play nicely with having more than one set of routes. This check should only apply to some-routes and not other-routes. But until we execute the handler we don't know if the route matches. And at that point the handler has already executed. I could rewrite it to execute handler and then only perform the check if the response is non-nil, but this means I've executed a handler before checking for auth.
I followed this example, which exhibits the problem:
(defn add-app-version-header [handler]
(fn [request]
(let [resp (handler request)
headers (:headers resp)]
(assoc resp :headers
(assoc headers "X-APP-INFO" "MyTerifficApp Version 0.0.1-Alpha")))))
How do I do this? What I want is:
- a way of checking a response (and some other logic) before handling a request
- that I can apply to a large-ish set of routes' handlers
- that isn't applied to all routes in the app
- I will have more than one such handler doing a different kind of check on the session
How should I go about doing this?