2

我想使用Wai HttpAuth 中间件在 HTTP 基本身份验证后面隐藏几页。为此,HttpAuth 中间件提供authIsProtected :: !(Request -> IO Bool).

要实现authIsProtected,我需要检查 URL 是否仅限管理员;似乎最好的方法是在文件中创建路由属性routes,然后使用此函数访问它们routeAttrs :: RouteAttrs a => Route a -> Set Text

但是,我无法访问函数Route中的a authIsProtected,只能访问 Wai Request。有没有办法可以从一个围Request到一个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
4

1 回答 1

1

parseRoute是否为您提供了您正在寻找的东西?您只需要将它与pathInfoqueryString组合起来。

于 2014-10-05T11:51:10.487 回答