我正在尝试将好友身份验证和授权集成到Clojure/Compojure单页面Web应用程序中。
我有一个由Angular控制器支持的登录表单,该控制器使用AJAX针对Web应用程序验证用户名和密码,并获取已认证的用户记录。因此,我不希望使用Friend基于表单的默认行为 - 我基本上希望依赖HTTP状态代码,并且我不希望任何Friend页面重定向。
例如,进行未经身份验证的请求应仅返回401状态代码,而不应重定向到“/login”。通过在配置Friend时指定自定义“:unauthenticated-handler”来实现此部分(包含在下面的代码中)。
成功登录后,我只想要一个200状态代码,而不是重定向到最初请求的页面。这是我无法让其工作的部分。
我根据各种示例编写了一个基于自定义Friend身份验证工作流程的代码(我的Clojure技能目前处于初学者水平)。
我有一个由Angular控制器支持的登录表单,该控制器使用AJAX针对Web应用程序验证用户名和密码,并获取已认证的用户记录。因此,我不希望使用Friend基于表单的默认行为 - 我基本上希望依赖HTTP状态代码,并且我不希望任何Friend页面重定向。
例如,进行未经身份验证的请求应仅返回401状态代码,而不应重定向到“/login”。通过在配置Friend时指定自定义“:unauthenticated-handler”来实现此部分(包含在下面的代码中)。
成功登录后,我只想要一个200状态代码,而不是重定向到最初请求的页面。这是我无法让其工作的部分。
我根据各种示例编写了一个基于自定义Friend身份验证工作流程的代码(我的Clojure技能目前处于初学者水平)。
(defn my-auth
[& {:keys [credential-fn]}]
(routes
(GET "/logout" req
(friend/logout* {:status 200}))
(POST "/login" {{:keys [username password]} :params}
(if-let [user-record (-> username credential-fn)]
(if
(and
[user-record password]
(creds/bcrypt-verify password (:password user-record)))
(let [user-record (dissoc user-record :password)]
(workflows/make-auth user-record {:cemerick.friend/workflow :my-auth :cemerick.friend/redirect-on-auth? true}))
{:status 401})
{:status 401}))))
这里是我的带有中间件声明的处理程序:
(def app
(->
(handler/site
(friend/authenticate app-routes
{:credential-fn (partial creds/bcrypt-credential-fn my-credential-fn)
:unauthenticated-handler unauthenticated
:workflows [(my-auth :credential-fn my-credential-fn)]}))
(session/wrap-session)
(params/wrap-keyword-params)
(json/wrap-json-body)
(json/wrap-json-response {:pretty true})))
还有上面引用的额外处理函数:
(defn unauthenticated [v]
{:status 401 :body "Unauthenticated"})
最后,还需要一个额外的路由片段来测试身份验证:
(GET "/auth" req
(friend/authenticated (str "You have successfully authenticated as "
(friend/current-authentication))))
这个功能基本上可用,几乎满足我的需求。
因为在“make-auth”中“redirect-on-auth?”的值为true,所以在成功登录后会生成一个页面重定向 - 我想阻止该重定向,因此将该值设置为false。然而,这个单一的更改导致了404和登录失败。
因此,除了Friend身份验证映射之外,我还需要以某种方式返回200状态代码,并且我希望在响应正文中返回“user-record”,以便客户端应用程序可以根据用户角色调整UI(我已经包装并使用JSON请求/响应)。
因此,当我调用Friend“make-auth”函数时,我认为我需要相应的等效物:
{:status 200 :body user-record}
然而,似乎我只能获取验证映射或响应,而不能同时获取两者。
如果可以的话,Friend如何实现这一点?