Authentication 在Clojure Web应用程序中使用JSON请求体而不是请求参数进行朋友身份验证
我正在使用Friend将身份验证构建到Compojure web应用程序中 我已经为朋友定义了一个定制的身份验证工作流:Authentication 在Clojure Web应用程序中使用JSON请求体而不是请求参数进行朋友身份验证,authentication,clojure,compojure,Authentication,Clojure,Compojure,我正在使用Friend将身份验证构建到Compojure web应用程序中 我已经为朋友定义了一个定制的身份验证工作流: (defn authentication-workflow [] (routes (GET "/logout" req (friend/logout* {:status 200})) (POST "/login" {{:keys [username password]} :params} (if-let [user-record (
(defn authentication-workflow []
(routes
(GET "/logout" req
(friend/logout* {:status 200}))
(POST "/login" {{:keys [username password]} :params}
(if-let [user-record (authenticate-user username password)]
(workflows/make-auth user-record {:cemerick.friend/workflow :authorisation-workflow})
{:status 401}))))
身份验证部分已考虑在内:
(defn authenticate-user [username password]
(if-let [user-record (get-user-for-username username)]
(if (creds/bcrypt-verify password (:password user-record))
(dissoc user-record :password))))
这是可行的,但是
我正在使用AngularJS,并且必须发布请求参数,这会导致一些丑陋的角度代码(抄袭StackOverflow答案的其他地方):
我更愿意执行这个简单得多的调用,通过请求体发布一个JSON对象:
$http.post('/login', {username: username, password: password})
(defn authentication-workflow []
(routes
(GET "/logout" req
(friend/logout* {:status 200}))
(POST "/login" {body :body}
(if-let [user-record (authenticate-user body)]
(workflows/make-auth user-record {:cemerick.friend/workflow :authorisation-workflow})
{:status 401}))))
我试图在身份验证处理程序中使用“:body”而不是“:params”,但是:body的值在我看来既不是JSON也不是Clojure,所以我不知道如何使用它:
{username me@myapp.com, password password}
我已经让JSON请求/响应映射工作流为我的RESTAPI处理程序正常工作,并且我已经检查了JSON的请求头(例如ContentType)是否正确
那么,使用Compojure/Friend可以做到这一点吗?如果可以,如何做到呢?我怀疑您的包装程序的应用顺序是错误的。检查
ring.middleware.json/wrap json body
是否在友元包装器之前(外部)应用
e、 g
否则,一个快速修复方法可能是将整个应用程序包装到
ring.middleware.json/wrap json params
以下是一些工作代码和说明
首先是朋友工作流,使用请求正文:
$http.post('/login', {username: username, password: password})
(defn authentication-workflow []
(routes
(GET "/logout" req
(friend/logout* {:status 200}))
(POST "/login" {body :body}
(if-let [user-record (authenticate-user body)]
(workflows/make-auth user-record {:cemerick.friend/workflow :authorisation-workflow})
{:status 401}))))
第二,身份验证功能:
(defn authenticate-user [{username "username" password "password"}]
(if-let [user-record (get-user-for-username username)]
(if (creds/bcrypt-verify password (:password user-record))
(dissoc user-record :password))))
第三,使用中间件的Compojure应用程序声明:
(def app
(-> (handler/site
(friend/authenticate app-routes
{:workflows [(authentication-workflow)]}))
(params/wrap-keyword-params)
(json/wrap-json-body)
(json/wrap-json-response {:pretty true})))
最后,发布凭证的AngularJS代码片段(用户名和密码来自AngularJS模型):
所以发生的事情是
javascript代码将JSON发布到web应用程序登录URL。“Content Type”头自动设置为“application/json”,请求主体自动编码为json,例如:
{"username":"batman@batcave.org","password":"tumblerrocks"}
在服务器上,中间件将JSON解析为Clojure映射,并通过“:body”关键字将其呈现给处理程序:
然后将请求路由到自定义好友身份验证工作流
最后,从Clojure映射中提取提交的值并用于对用户进行身份验证
{"username":"batman@batcave.org","password":"tumblerrocks"}
{username batman@batcave.org, password tumblerrocks}