database - Haskell Servant 将自定义数据传递给授权处理程序

标签 database haskell authentication pool servant

我正在使用自定义 monad(带有读取器)轻松地将数据库池等数据传递给我的处理程序(在使用自定义 monad 之前,我曾经将连接作为 fn 参数传递)。

这就是我定义自定义 monad 的方式:

newtype Controller a = Controller
    { runController :: ReaderT ServerEnvironment Handler a
    } deriving ( Functor, Applicative, Monad, MonadReader ServerEnvironment, 
                 MonadError ServantErr, MonadIO )

ServerEnvironment 只是我用来承载数据的自定义数据类型。

问题是,对于我的 AuthHandler,我必须专门使用函数:

r -> Handler usr

作为身份验证处理程序,我不能使用我的自定义处理程序:

r -> Controller usr

而且我也无法传入我的 ConnectionPool 因为签名不能是:

ConnPool -> r -> Handler usr

那么,如何在不使用全局 IO 状态的情况下将额外数据传递给 servant 中的身份验证处理程序?

最佳答案

您放入上下文中的 AuthHandler 不必在顶层定义!通常,您需要在 main 中执行此操作,以便您可以访问您创建的数据库连接等:

type API = 
  ... :<|> (AuthProtect "myProtection" :> ...) :<|> ...

type instance AuthServerData (AuthProtect "myProtection") = User

server :: ServerEnvironment -> Server API
server env = ...

setupEnv :: IO ServerEnvironment
setupEnv = ..

-- This is essentially a 'Controller'.
authenticate :: ServerEnvironment -> Handler User
authenticate conn = ...

main :: IO ()
main = do
  env <- setupEnv
  -- Now, because we have access to the env, we can turn our
  -- 'authenticate' into the right type before putting it
  -- in the context
  let ctx = authenticate env :. EmptyContext
  run 8080 $ serveWithContext myAPI (server conn) ctx

关于database - Haskell Servant 将自定义数据传递给授权处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41320350/

相关文章:

authentication - 无法使用 Auth0 获取委托(delegate) token

php - 将非常大的 MySQL 数据库中的特定表/列备份并压缩到不同的服务器上

php - 如何在 mysql 数据库表中获取第一个和最后一个日期

haskell - Yesod应用形式

haskell - 为什么 `Bits` 依赖于 `Num` ?

Android共享首选项检索用户名和密码

mysql - SQL 将 "non-existing"行添加到基于所有变体的结果中并删除重复项

php pdo一次插入太多行的有效方法

performance - Haskell 斐波那契序列性能取决于方法

java - 错误: Value Fatal of type java. lang.String无法转换为JSONObject