2016-06-30 105 views
1

完全重寫,包括改善的理解耶索德:靜子網站與授權

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等情況下失敗。由於這些原因,我無法弄清楚如何添加支票。任何指針將不勝感激。

回答

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中沒有任何路由工具,因此您必須手動執行並取消選中。
  • 此子網站中的所有路由都應該是相對的,這樣在將服務器從開發移動到部署時,您可以獲得更少的錯誤。這可能不是一個缺點,但它限制了你的選擇。

是否值得努力創建一個子網站來捆綁這三個處理程序?那麼,也許作爲一個訓練練習...