我想使用Wai HttpAuth 中间件 http://hackage.haskell.org/package/wai-extra/docs/Network-Wai-Middleware-HttpAuth.html隐藏 HTTP 基本身份验证后面的几个页面。为此,HttpAuth 中间件提供了authIsProtected :: !(Request -> IO Bool)
.
实施authIsProtected
我需要检查该 URL 是否仅限管理员使用;似乎最好的方法就是创建路由属性 http://www.yesodweb.com/book/route-attributes in the routes
文件,然后使用以下函数访问它们:routeAttrs :: RouteAttrs a => Route a -> Set Text
.
但是,我无权访问Route
in the authIsProtected
功能,只是一个围Request
。有什么办法可以让我从Wai去Request
to a Route
?我认为 Yesod 一定在幕后做这件事,但我不知道在哪里/如何做。
我可能应该在中进行身份验证isAuthorized
相反,我可以访问Route
,但我不确定是否可以从那里运行 HTTP 基本身份验证。
makeApplication :: AppConfig DefaultEnv Extra -> IO Application
makeApplication conf = do
foundation <- makeFoundation conf
app <- toWaiAppPlain foundation
return $ basicAuth
(\u p -> return $ u == "username" && p == "password")
("My Realm" { authIsProtected = \waiRequest -> do
-- Would like to access a route / route attrs here
return True } :: AuthSettings)
$ app
编辑:这是我想出的:
import Network.Wai (queryString, pathInfo, Request)
import Network.HTTP.Types.URI (queryToQueryText)
import Control.Arrow (second)
import Data.Maybe (fromMaybe)
import Yesod (Route)
import Data.Set (member)
makeApplication :: AppConfig DefaultEnv Extra -> IO Application
makeApplication conf = do
foundation <- makeFoundation conf
-- Create the WAI application and apply middlewares
app <- toWaiAppPlain foundation
return $ basicAuth
(\u p -> return $ u == "username" && p == "password")
("My Realm" { authIsProtected = \waiReq -> do
let mRoute = parseRoute(pathInfo waiReq,textQueryString waiReq) :: Maybe (Route App)
return $ maybe False adminOnly mRoute
} :: AuthSettings)
$ app
adminOnly :: Route App -> Bool
adminOnly r = "admin" `member` routeAttrs r
-- Copied from Yesod.Core.Internal.Request
textQueryString :: Request -> [(Text, Text)]
textQueryString = map (second $ fromMaybe "") . queryToQueryText . queryString