【发布时间】:2015-10-09 19:39:25
【问题描述】:
我正在编写一个使用 Ring 和 Compojure 的网络应用程序,以及用于授权的 Friend 库。最近对项目做了一些改动,现在无法获取请求参数了。
我以前的做法是这样的:
; Routes definition
(defroutes app-routes
(POST "/*.do" request
(insert-data (:params request))))
; Middlewares
(def secured-routes
(handler/site
(-> app-routes
wrap-params
(friend/authenticate friend-params-map))))
和表单/URL 参数将被解析为 Clojure 映射。现在这似乎不起作用,(:params request) 包含表单的映射
{:* <request-url>}
使用单个 :* 键。如果我尝试(println request),得到一个包含很多键值对的 Clojure 映射,其中有
:body #object[org.eclipse.jetty.server.HttpInputOverHTTP 0x6ef9a9e1 HttpInputOverHTTP@6ef9a9e1]
似乎包含请求数据,对吗?但是我该如何获取这些呢?
以前我只是使用如上所述的wrap-params 中间件,它确实有效。
一种可行的方法是在每个处理程序中调用(body-string request),这将返回请求正文的字符串化版本。但是为每个 url 处理程序获得一个自动解析的 Clojure 映射会很棒。显然,我错过了一些东西。
有人可以建议吗?我也很乐意了解更多如何自己调试这些处理程序问题 - 意思是调试中间件链并找出为什么 wrap-params 没有被调用或调用不正确。
谢谢!
更新:根据@nberger 的评论,我尝试将secured-routes 定义更改为:
(def secured-routes
(-> app-routes
(wrap-defaults site-defaults)
(friend/authenticate friend-params-map)))
但现在登录页面根本不起作用(身份验证停止工作)。按照评论中的建议将wrap-defaults移到friend/authenticate之后,朋友用大字体抱怨无效的防伪令牌(???)
【问题讨论】:
-
您是否尝试过删除
friend/authenticate中间件?您还可以删除显式的wrap-params,因为 compojure.handler/site 已经包含它。有一个最小的例子会很棒。顺便说一句, compojure.handler 已弃用,您可能想使用ring-defaults -
感谢您的评论。我已经更新了原始问题。我不知道
handler/site已被弃用。 -
friend-authenticate必须被wrap-defaults包裹,因为它假定参数已经在form-params或params中,所以你应该有:(-> app-routes (wrap-defaults site-defaults) (friend/authenticate friend-params-map)) -
对不起,你应该有:
(-> app-routes (friend/authenticate friend-params-map) (wrap-defaults site-defaults)) -
ring-defaults 默认包含防伪保护。您通常应该使用它,但如果您想禁用它,您可以使用
(wrap-defaults (assoc-in site-defaults [:security :anti-forgery] false))而不仅仅是(wrap-defaults site-defaults)。有关所有选项,请参阅 the readme