38 middleware routes clojure compojure ring
我目前正在使用Compojure(以及Ring和相关的中间件)在Clojure中编写API.
我正在尝试根据路由应用不同的身份验证代码.请考虑以下代码:
(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?)))))
Run Code Online (Sandbox Code Playgroud)
这不能按预期工作,因为它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?))))))
Run Code Online (Sandbox Code Playgroud)
我想知道我是否遗漏了某些东西,或者是否有任何方式可以实现我想要的而不受约束defroutes而不使用公共基本路径(理想情况下,没有任何东西).
ved*_*ang 20
(defroutes user-routes*
(GET "-endpoint1" [] ("USER ENDPOINT 1"))
(GET "-endpoint2" [] ("USER ENDPOINT 1")))
(def user-routes
(-> #'user-routes*
(wrap-basic-authentication user-auth?)))
(defroutes admin-routes*
(GET "-endpoint" [] ("ADMIN ENDPOINT")))
(def admin-routes
(-> #'admin-routes*
(wrap-basic-authentication admin-auth?)))
(defroutes main-routes
(ANY "*" [] admin-routes)
(ANY "*" [] user-routes)
Run Code Online (Sandbox Code Playgroud)
这将首先通过管理路由然后通过用户路由运行传入请求,在两种情况下应用正确的身份验证.这里的主要想法是,nil如果调用者无法访问路由而不是抛出错误,则应返回您的身份验证函数.这样,如果a)路由实际上与定义的管理路由不匹配,或者b)用户没有所需的身份验证,则admin-routes将返回nil.如果admin-routes返回nil,则compojure将尝试用户路由.
希望这可以帮助.
编辑:我在一段时间后写了一篇关于Compojure的帖子,你可能觉得它很有用:https://vedang.me/techlog/2012-02-23-composability-and-compojure/
Jul*_*lio 16
我偶然发现了这个问题,似乎wrap-routes(compojure 1.3.2)优雅地解决了这个问题:
(def app
(handler/api
(routes
public-routes
(-> user-routes
(wrap-routes wrap-basic-authentication user-auth?)))))
(-> admin-routes
(wrap-routes wrap-basic-authentication admin-auth?)))))
Run Code Online (Sandbox Code Playgroud)
小智 1
我刚刚发现以下不相关的页面解决了相同的问题:
http://compojureongae.posterous.com/using-the-app-engine-users-api-from-clojure
我没有意识到可以使用这种类型的语法(我尚未测试过):
(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
(ANY "/user*" []
(-> user-routes
(wrap-basic-authentication user-auth?)))
(ANY "/admin*" []
(-> admin-routes
(wrap-basic-authentication admin-auth?))))))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8599 次 |
| 最近记录: |