clojure - 使用不同中间件的 Compojure 路由

标签 clojure routes middleware 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?)))))

这不能按预期工作,因为 wrap-basic-authentication 确实包装了路由,因此无论包装的路由如何,都会尝试它。具体来说,如果请求需要路由到 admin-routes,则仍会尝试 user-auth?(并失败)。

我求助于使用context公共(public)基础下的一些路由 路径,但它是一个很大的限制(下面的代码可能不起作用,它只是为了说明这个想法):

(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 并且不使用公共(public)基本路径(理想情况下,会有没有)。

最佳答案

(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/

关于clojure - 使用不同中间件的 Compojure 路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10822033/

相关文章:

clojure - Clojure 中函数名称中的箭头

css - 使用 express 中间件应用 CSS 样式

express - 如何在 Sails.js 中将 Stormpath 配置为中间件

java - ClojureScript 编译器如何将 cljs 转换为 Javascript

list - Clojure 列表成员转换错误

clojure - 'reduced' 函数有什么作用以及如何使用它

javascript - Express js为目录中的所有静态文件获取404

windows - 如何在 Windows 中刷新路由表?

带有多个名称的Laravel路线

go - 如何从中间件记录响应主体?