如何从"Wai Request"转到"Yesod Route"? [英] How can I go from a Wai Request to a Yesod Route?

查看:59
本文介绍了如何从"Wai Request"转到"Yesod Route"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'd like to use the Wai HttpAuth Middleware to hide a few pages behind HTTP basic auth. For this the HttpAuth middleware provides authIsProtected :: !(Request -> IO Bool).

要实现 authIsProtected ,我需要检查URL是否仅是管理员身份.似乎最好的方法是在中创建路由属性路由文件,然后使用此功能访问它们: routeAttrs :: RouteAttrs a =>路线a->设置文字.

To implement authIsProtected I need to check if the URL is admin-only; it seems like the best way to do that is to create route attributes in the routes file, then access them using this function: routeAttrs :: RouteAttrs a => Route a -> Set Text.

但是,我无权访问 authIsProtected 函数中的 Route ,而只能访问Wai Request .有什么方法可以使我从Wai Request 转到 Route ?我认为Yesod必须在后台进行此操作,但我不知道该在哪里/如何进行.

However, I don't have access to a Route in the authIsProtected function, just a Wai Request. Is there a way I can go from a Wai Request to a Route? I figure Yesod must do this under the hood but I couldn't figure out where/how.

有可能我应该在 isAuthorized 中进行身份验证,在这里我可以访问 Route ,但是我不确定我可以运行HTTP基本身份验证从那里.

Its possible I should be doing the authentication in isAuthorized instead, where I have access to the Route, but I'm not sure I can run the HTTP basic auth from there.

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

推荐答案

pathInfo组合在一起 queryString .

Does parseRoute provide you what you're looking for? You just need to team it up with pathInfo and queryString.

这篇关于如何从"Wai Request"转到"Yesod Route"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆