我想编写一个函数来检查用户的登录名和哈希密码是否存在于数据库中。假设 DB 非常简单:
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
User
login String
passHash Hash
UniqueL login
deriving Eq Show
https://hackage.haskell.org/package/password-2.0.1.1/docs/Data-Password-PBKDF2.htmlHash
的别名type Hash = PasswordHash PBKDF2
在哪里。
另外,为简单起见,我们假设登录名和密码都以String
.
模块中有一个名为checkPassword
( https://hackage.haskell.org/package/password-2.0.1.1/docs/Data-Password-PBKDF2.html#g:3 ) 的函数,用于检查密码是否产生所需的哈希值。但是,我不知道如何在 esqualetowhere_
子句中使用它。
我想出了这样的事情:
type DB m a = ReaderT SqlBackend m a
checkCredentials ::(MonadIO m, MonadLogger m) => (String, String) -> DB m Bool
checkCredentials (login, password) = do
let hashFunc = (checkPassword $ mkPassword (pack password))
res <-
select $
from $ \user -> do
-- This won't wwork
where_ (user ^. UserLogin ==. val login &&. hashFunc (user ^. UserPassHash) ==. val PasswordCheckSuccess)
return user
return (negate $ null res)
但是这部分hashFunc (user ^. UserPassHash)
显然是行不通的。我想我需要进入hashFunc
一个单子(或两个),但我不知道该怎么做。
我注意到那UserPassHash
是 type EntityField User Hash
。我想知道我怎样才能把它变成EntityField User PasswordCheck
.