Wai HttpAuth ミドルウェアを使用して、いくつかのページを HTTP 基本認証の背後に隠したいと考えています。このために、HttpAuth ミドルウェアが提供しますauthIsProtected :: !(Request -> IO Bool)
。
実装するauthIsProtected
には、URL が管理者専用かどうかを確認する必要があります。これを行う最善の方法は、ファイルにルート属性を作成し、次の関数を使用してそれらにアクセスすることです。routes
routeAttrs :: RouteAttrs a => Route a -> Set Text
ただし、関数内の aRoute
にはアクセスできずauthIsProtected
、 Wai だけにアクセスできますRequest
。WaiRequest
から に移行する方法はあり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