В настоящее время я пишу API в Clojure с помощью Compojure (и Ring и связанного с ними промежуточного программного обеспечения).
Я пытаюсь применить другой код аутентификации в зависимости от маршрута. Рассмотрим следующий код:
(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?)))))
Это не работает так, как ожидалось, потому что wrap-basic-authentication
действительно переносит маршруты, поэтому он проверяется независимо от обернутых маршрутов. В частности, если запросы должны быть перенаправлены на admin-routes
, user-auth?
будет по-прежнему проверяться (и сбой).
Я прибег к использованию context
для корневых маршрутов под общей базой
путь, но это довольно сложное (код ниже может не работать просто для иллюстрации идеи):
(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?))))))
Мне интересно, если я что-то упустил или вообще не смог добиться того, чего хочу, без ограничений на моем defroutes
и без использования общего базового пути (в идеале их не было бы).