I'm currently writing an API in Clojure using Compojure (and Ring and associated middleware).
I'm trying to apply different authentication code depending on the route. Consider the following code:
(defroutes public-routes
(GET "/public-endpoint" [] ("PUBLIC ENDPOINT")))
(defroutes user-routes
(GET "/user-endpoint1" [] ("USER ENDPOINT 1"))
(GET "/user-endpoint2" [] ("USER ENDPOINT 1")))
(defroutes admin-routes
(GET "/admin-endpoint" [] ("ADMIN ENDPOINT")))
(def app
(handler/api
(routes
public-routes
(-> user-routes
(wrap-basic-authentication user-auth?)))))
(-> admin-routes
(wrap-basic-authentication admin-auth?)))))
This doesn't work as expected because wrap-basic-authentication
indeed wraps routes so it gets tried regardless of the wrapped routes. Specifically, if the requests needs to be routed to admin-routes
, user-auth?
will still be tried (and fail).
I resorted to use context
to root some routes under a common base
path but it's quite a constraint (the code below may not work it's simply to illustrate the idea):
(defroutes user-routes
(GET "-endpoint1" [] ("USER ENDPOINT 1"))
(GET "-endpoint2" [] ("USER ENDPOINT 1")))
(defroutes admin-routes
(GET "-endpoint" [] ("ADMIN ENDPOINT")))
(def app
(handler/api
(routes
public-routes
(context "/user" []
(-> user-routes
(wrap-basic-authentication user-auth?)))
(context "/admin" []
(-> admin-routes
(wrap-basic-authentication admin-auth?))))))
I'm wondering if I'm missing something or if there's any way at all to achieve what I want without constraint on my defroutes
and without using a common base path (as ideally, there would be none).
question from:
https://stackoverflow.com/questions/10822033/compojure-routes-with-different-middleware 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…