对于这个简单的逻辑,什么是惯用的Clojure?
我用Clojure编写了一个简单的人工编写的auth函数,我觉得它一点也不习惯。有没有更好的写作方法:对于这个简单的逻辑,什么是惯用的Clojure?,clojure,idioms,Clojure,Idioms,我用Clojure编写了一个简单的人工编写的auth函数,我觉得它一点也不习惯。有没有更好的写作方法: (defn auth [username password] (let [user-record (credential-fn username)] (if (and user-record (verify-pw password)) (let [user-record (dissoc user-record :password)] {:status
(defn auth [username password]
(let [user-record (credential-fn username)]
(if (and user-record (verify-pw password))
(let [user-record (dissoc user-record :password)]
{:status 200 :body user-record})
{:status 401})))
我认为可以通过使用if let
摆脱if
,但是if
正在进行布尔检查,我需要绑定用户记录
?卡住了
注意:
dissoc
正在从用户记录中删除密码,因此它不会返回到正文中。我认为您的函数最大的问题是它试图同时处理三件事:
检查用户名和密码是否对用户有效(凭证fn
和验证pw
)
清理记录数据(dissoc用户记录密码)
构建环形响应图({:status 401}
vs.{:status 200:body user record}
)
我将把你的代码分成两个独立的函数:
(defn authenticate
[username password]
(and (verify-pw password)
(dissoc (credential-fn username) :password)))
(defn login
[username password]
(if-let [user-record (authenticate username password)]
{:status 200 :body user-record}
{:status 401}))
我更喜欢这个版本,因为它将事物分割成不同的函数,这正是我想要的。这里唯一的问题是,在通过凭证fn
读取用户记录之前执行验证pw
,这对于这个人为的示例很好,但我认为在实际场景中,我需要先读取用户记录,然后验证密码,但这会使身份验证返回布尔值,不是吗,阅读login
时,authenticate
是否会从地图中删除密码并不明显。对我来说,这将是登录的责任,因为它处理的是响应映射。@PaulDrummond,我大部分时间只是将您的代码重新排序(因此顺序可能不正确)。这看起来很奇怪,因为无论是verify pw
还是credential fn
都不需要用户名和密码来检查用户是否有效。在我的例子中,我试图描述认证用户是低级逻辑(服务逻辑?)和清理敏感数据的数据,例如密码应该在那里完成。我会考虑一些(和(用户存在的用户名)(验证盘用户名密码)(凭据fn用户名))。并定义凭证fn,以不返回密码或密码散列等潜在“风险”数据。这将降低某人犯简单错误的可能性。实际上,您可能需要一些更复杂的东西,因为当前示例没有反馈有关身份验证失败原因的任何信息,例如错误的用户名或错误的密码等。