Yesod:具有授权

时间:2016-06-30 05:44:43

标签: haskell yesod

完全重写以包含更好的理解

Yesod类型类包含您可以调整的函数isAuthorized,以便不同的用户组只能访问不同的路由。  脚手架网站显示了如何执行此操作的示例,包括使授权子网站可供所有人使用:

isAuthorized (AuthR _) _ = return Authorized

脚手架网站还有助于包含静态内容的子网站。但是:静态子网站不尊重您在isAuthorized中所做的事情。您可以通过添加类似

的模式匹配来检查
isAuthorized (StaticR _) _ = error "this error is never reached"

您仍然可以访问所有静态内容(包括新创建的内容),您将永远不会遇到此模式匹配。

让每个人都能访问bootstrap或jquery等内容确实有点意义。尽管如此,可以通过尊重isAuthorized并始终返回Authorized来实现相同的结果,就像使用授权子网站或favicon处理程序一样。

我个人想进一步发送像

这样的发送
isAuthorized (StaticR (StaticRoute ("public":_) _)) _     = pure Authorized
isAuthorized (StaticR (StaticRoute ("admin" :_) _)) _     = checkIsAdmin
isAuthorized (StaticR (StaticRoute ("cats"  :_) _)) False = checkIsAllowedToViewCats
:

似乎唯一缺少的是让静态子网站接受检查或添加一个垫片。

可悲的是,子网站是一个庞大的复杂代码,其中包含模板haskell和很多魔术,可以执行复杂的操作,例如在可执行文件中嵌入文件。它包含在脚手架中的方式还有更多的魔力。我也只是学习子网站和我的培训,看到类型作为文档在类型系列或Q Def等上下文中失败。由于这些原因,我无法弄清楚如何添加支票。任何指针都会受到赞赏。

1 个答案:

答案 0 :(得分:1)

所以我发现了一个不完美的答案,这对我现在的目的来说已经足够了。

我无法弄清楚如何使静态网站的行为不同。它似乎以某种方式使用了wai服务器的底层功能,因此它甚至从未接触到它的Yesod部分。并且由于子网站似乎在核心系统之前进行调度,这是我可以改变某些东西的唯一地方。让核心系统排在最后的奇怪选择,但无论如何,这可能是有原因的。

然后,解决方案是复制静态子网站的功能。但请尽可能少地工作。所以这是你可以创建的最基本的处理程序:

getStaticCatContentHtmlR :: Text -> Handler Value
getStaticCatContentHtmlR path = do
  let filePath = "static/cats/html" </> unpack path
  sendFile "text/html" filePath

只需将您的静态子网站指向static/public,为每个子网站为html,css和js创建三个新的子文件夹,添加三个具有适当权限的相应处理程序并完成它。路由系统确保用户无法请求/static/cats/html/../../../等路径。

但是有几个缺点。

  • Yesod无法做任何优化。
  • 丢失文件或错误路由的错误不会导致服务器崩溃,但错误响应非常糟糕。当然你可以自己发现错误。
  • 您在Yesod中没有获得任何路由工具,因此您必须手动执行此操作并取消选中。
  • 此子网站中的所有路由都应该是相对的,因此当您将服务器从开发移动到部署时,您可以获得更少的错误。这可能不是一个缺点,但它限制了你的选择。

是否值得努力创建一个子网站来捆绑这三个处理程序?好吧,也许是作为训练练习......