我正在使用可用于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传递给经过身份验证的?功能
感谢。
答案 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-authentication
和wrap-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?)))
正如我所说,我没有测试过这段代码,但它应该让你开始。