1

我想编写一个函数来检查用户的登录名和哈希密码是否存在于数据库中。假设 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.

4

0 回答 0