Compojure:从basic-auth函数内部访问请求参数?

时间:2014-08-26 05:56:00

标签: clojure basic-authentication compojure ring

我正在使用可用于compojure的环基本身份验证库。经过验证的?函数需要用户名和密码才能进行身份验证,但在我的特定情况下,除了用户名和密码之外,我还需要访问用户请求传入的其他参数。

例如,考虑一种情况,即有多个服务器,并且用户在特定服务器上拥有帐户。因此,该用户需要对特定服务器进行身份验证(登录)。因此我需要他的用户名,密码和服务器来进行身份验证。

处理一个只调用用户名和密码的“正常”情况可能看起来像这样(使用示例sql命中数据库):

; curl my_id:my_pass@localhost/my_request

(defn authenticated? [id password]
  (first (select user (where {:id id :password password}) (limit 1))))

我想做这样的事情:

; curl my_id:my_pass@localhost/my_server/my_request

(defn authenticated? [id password ??server??]
  (first (select user (where {:server server :id id :password password}) (limit 1))))

我想我的问题是,我如何从经过身份验证的内部访问所有请求参数?或者,或者,如何将服务器ID传递给经过身份验证的?功能

感谢。

1 个答案:

答案 0 :(得分:2)

根据上述问题的评论,这种方法看起来像这样(只是草图,我还没有测试过这是否有效,因为缺少带环的运行设置):

(defn wrap-basic-auth-server [handler authfn]
 (fn [request]
   (-> request
       (wrap-basic-authentication (partial authfn (get-in request [:params :server])))
       handler)))

这里发生的是代码假设您的服务器URL参数将由wrap-params(来自ring.middleware.params)添加到请求映射中。然后使用处理程序(典型的环中间件,即之后的任何其他包装器/处理程序)和新的(部分)函数调用wrap-basic-authentication,这只是您已经吞服服务器arg的身份验证函数。

然后,您需要添加wrap-basic-authenticationwrap-params,而不是仅仅在路线中调用wrap-basic-auth-server,而您需要新的身份验证功能。 E.g。

(defn authenticated? [server user pass]
   ... your code ...)

(def app 
    (-> app-routes
        ... potential other wrappers elided ...
        (wrap-params)
        (wrap-basic-auth-server authenticated?)))

正如我所说,我没有测试过这段代码,但它应该让你开始。