使用带有仆人的自定义 Reader Monad 进行身份验证
Using Authentication With a Custom Reader Monad With Servant
受基本身份验证保护的 API
type SubApi = API1 :<|> API2 :<|> API3
type API = BasicAuth "foo-realm" AuthData :> SubApi
支持 AuthData -> Handler a
类型的处理程序。
我有一组处理程序:
handler1 :: Request1 -> AuthMonad Response
handler2 :: Request2 -> AuthMonad Response
AuthMonad 中的 运行,这是一个 ReaderT,其上下文部分由 AuthData 构建。
使用 enter
和 AuthMonad :~> Handler
,我可以获得 Server API
支持类型 AuthData -> AuthMonad
的处理程序,但我真正想做的是使用 AuthData
参数作为 运行ReaderT.
的环境
我不太了解 enter
的类型魔法,无法理解如何做到这一点。有任何想法吗?
刚意识到我把这个挂了。
大多数情况下,只是想得太多了——答案很明显。
在上面的例子中,我创建了一个函数来创建自然变换:
enterAuth :: AuthData -> AuthMonad :~> Handler
然后我在构建 ServerT 时使用了它:
protectedServer :: AuthData -> ServerT ProtectedAPI Handler
protectedServer ad = enter (enterAuth ad) protectedServer'
哪里
genAuthServerContext :: Context (AuthHandler Request AuthData ': '[])
受基本身份验证保护的 API
type SubApi = API1 :<|> API2 :<|> API3
type API = BasicAuth "foo-realm" AuthData :> SubApi
支持 AuthData -> Handler a
类型的处理程序。
我有一组处理程序:
handler1 :: Request1 -> AuthMonad Response
handler2 :: Request2 -> AuthMonad Response
AuthMonad 中的 运行,这是一个 ReaderT,其上下文部分由 AuthData 构建。
使用 enter
和 AuthMonad :~> Handler
,我可以获得 Server API
支持类型 AuthData -> AuthMonad
的处理程序,但我真正想做的是使用 AuthData
参数作为 运行ReaderT.
我不太了解 enter
的类型魔法,无法理解如何做到这一点。有任何想法吗?
刚意识到我把这个挂了。
大多数情况下,只是想得太多了——答案很明显。 在上面的例子中,我创建了一个函数来创建自然变换:
enterAuth :: AuthData -> AuthMonad :~> Handler
然后我在构建 ServerT 时使用了它:
protectedServer :: AuthData -> ServerT ProtectedAPI Handler
protectedServer ad = enter (enterAuth ad) protectedServer'
哪里
genAuthServerContext :: Context (AuthHandler Request AuthData ': '[])