在单页Clojure Web应用程序中使用Friend进行身份验证和授权

 幽雅闲居xl 发布于 2023-02-13 22:58

我正在尝试将Friend身份验证和授权集成到Clojure/Compojure单页Web应用程序中.

我有一个由Angular控制器支持的登录表单,该控制器使用AJAX对Web应用程序验证用户名和密码,并获取经过身份验证的用户记录.因此,我不希望Friend基于表单的登录提供默认行为 - 我基本上想要依赖HTTP状态代码,而且我想要任何朋友页面重定向.

例如,制作未经身份验证的请求应该只返回401状态代码,而不应重定向到"/ login".我通过在配置好友时指定自定义的":unauthenticated-handler"(下面包含的代码)来完成此部分.

在成功登录后,我只需要200状态代码,而不是重定向到最初请求的页面.这是我无法工作的.

我根据各种示例编写了一个自定义的朋友身份验证工作流程(我的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))))

主要是有效的,几乎可以完成我需要的一切.

因为"redirect-on-auth?" 在"make-auth"中成功,在成功登录时生成页面重定向 - 我想阻止该重定向,因此我将值设置为false.但是,此单个更改会导致404和登录失败.

因此,除了Friend身份验证映射,我还需要以某种方式返回200状态代码,并且我还想在响应正文中返回"用户记录",以便客户端应用程序可以根据用户角色定制UI(I已经有JSON请求/响应包装和工作).

因此,当我调用Friend"make-auth"函数时,我认为我需要等效于此:

{:status 200 :body user-record}

然而,似乎我可以拥有身份验证映射或响应 - 但不能同时拥有两者.

这可以通过朋友实现,如果是这样的话怎么样?

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有