对于上下文,这是一种身份验证情况。在我的应用程序中,如果客户端没有经过身份验证,那么应用程序显然需要做出适当的响应。当我想根据调用服务器的应用程序类型选择不同的响应时,挑战就出现了。
下面是一个路由示例:
server = Header "Cookie" (AuthToken Unverified)
:> "api" :> "history" :> Get '[HTML, JSON] HistoryPage
因此,HTML 响应将针对 CGI 应用程序。通常,它应该呈现一个身份验证页面,或者它应该抛出一个 303 以将用户引导到一个身份验证页面。
但是 JSON 响应将用于 Javascript 应用程序,我想简单地返回 404,因为 Javascript 将有其他方式进行身份验证。
这是我的顶级处理程序:
newtype WebM a = WebM (ReaderT Context (ExceptT WebExc IO) a)
data WebExc = OtherExceptionTypes
| AppUnauthorized
runWeb :: Context -> WebM :~> Handler
runWeb ctx@Context{..} = Nat $ \(WebM action) -> withExceptT trExc $ runReaderT action ctx
where
trExc :: WebExc -> ServantErr
trExc AppUnauthorized = err303 { .. }
我尝试创建自己的 Javascript 内容类型,但 MimeRenderer 不允许我抛出异常。到目前为止,我唯一的想法是捕获“接受”标头并在处理程序内303
或404
从处理程序中抛出。但这很糟糕,因为处理程序不应该知道有关实际客户端应用程序的任何信息。
有没有更清洁的方法来处理这个?