如何在环应用程序中验证路由的子集?

时间:2018-02-23 17:50:18

标签: clojure compojure ring

我有两组compojure路由,公共路由,不需要身份验证,私有路由需要身份验证。

(defroutes public-routes
  (GET "/" [] homepage-handler))

(defroutes private-routes
  (GET "/secrets" [] secrets-handler))

我创建了一个中间件,检查用户是否经过身份验证,并继续中间件链或加注。

(defn wrap-must-be-authenticated [handler]
  (fn [request]
    (if (authenticated? request)
      (handler request)
      (throw-unauthorized))))

(def app
  (-> private-routes
      (wrap-must-be-authenticated)))

这很好,所有“私有路由”都需要身份验证。

如何添加public-routes以便将其排除在wrap-must-be-authenticated之外?

我相信defroutes会返回响铃处理程序,因此我认为我需要执行以下操作:

(-> (wrap-must-be-authenticated private-routes)
     public-routes)

1 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是在包含routes中放置多个routes定义,并在中间件中包装(wrap-routes)适当的路由以限制访问:

(def all-routes
  (routes
    (-> #'private-routes
        (wrap-routes wrap-must-be-authenticated))

    #'public-routes

    (route/not-found
      (:body
        (error-page {:status 404
                     :title "page not found"})))))

我使用buddy.auth restrict项目的另一个例子:

(defn wrap-admin [handler]
  (restrict handler {:handler (fn [req]
                                (boolean (get-in req [:session :admin?])))}))

(def app-routes
  (routes
    (-> #'admin-routes
        (wrap-routes wrap-admin)
        (wrap-routes middleware/wrap-csrf)
        (wrap-routes middleware/wrap-formats))
    (-> #'home-routes
        (wrap-routes middleware/wrap-csrf)
        (wrap-routes middleware/wrap-formats))))
相关问题