【问题标题】:Yesod: Static subsite with authorizationYesod:具有授权的静态子站点
【发布时间】:2016-11-02 01:27:57
【问题描述】:

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

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

isAuthorized (AuthR _) _ = return Authorized

脚手架网站还包括一个用于静态内容的子网站。但是:该静态子站点不尊重您在isAuthorized 中所做的事情。您可以通过添加类似的模式匹配来检查

isAuthorized (StaticR _) _ = error "this error is never reached"

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

让每个人都可以访问诸如 bootstrap 或 jquery 之类的内容确实有点道理。尽管如此,通过遵守 isAuthorized 并始终返回 Authorized 可以实现相同的结果,与授权子站点或网站图标处理程序的处理方式相同。

我个人希望通过像这样的调度更进一步

isAuthorized (StaticR (StaticRoute ("public":_) _)) _     = pure Authorized
isAuthorized (StaticR (StaticRoute ("admin" :_) _)) _     = checkIsAdmin
isAuthorized (StaticR (StaticRoute ("cats"  :_) _)) False = checkIsAllowedToViewCats
:

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

可悲的是,子站点是大量复杂的代码,带有模板 haskell 和很多复杂的东西,比如在可执行文件中嵌入文件。它包含在脚手架中的方式具有更多的魔力。我也只是在学习子站点和我的培训,以将类型视为文档在类型族或Q Def 等上下文中失败。由于这些原因,我无法弄清楚如何添加支票。任何指针将不胜感激。

【问题讨论】:

    标签: haskell yesod


    【解决方案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 中没有任何路由工具,因此必须手动执行且未选中。
    • 此子站点中的所有路由都应该是相对的,这样当您将服务器从开发迁移到部署时,错误会更少。这可能不是缺点,但会限制您的选择。

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

    【讨论】:

      猜你喜欢
      • 2015-01-27
      • 1970-01-01
      • 1970-01-01
      • 2015-06-30
      • 2017-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-02
      相关资源
      最近更新 更多