我目前正在使用 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?)))))
这不会按预期工作,因为wrap-basic-authentication
确实包装了路线,因此无论包装的路线如何,都会尝试它。具体来说,如果请求需要路由到admin-routes
, user-auth?
仍将被尝试(并失败)。
我求助于使用context
to root一些路线在共同基地下
路径,但它是一个很大的限制(下面的代码可能不起作用,它只是为了说明这个想法):
(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
并且不使用公共基本路径(理想情况下,不会有)。
(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)
这将首先通过管理路由运行传入请求,然后通过用户路由运行,在两种情况下应用正确的身份验证。这里的主要思想是您的身份验证函数应该返回nil
如果调用者无法访问该路由而不是抛出错误。这样,如果 a) 路由实际上与定义的管理路由不匹配或 b) 用户没有所需的身份验证,则管理路由将返回 nil。如果 admin-routes 返回 nil,则 compojure 将尝试 user-routes。
希望这可以帮助。
编辑:我不久前写了一篇关于 Compojure 的文章,您可能会发现它有用:https://vedang.me/techlog/2012-02-23-composability-and-compojure/ https://vedang.me/techlog/2012-02-23-composability-and-compojure/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)