我有一个简单的snaplet,它有自己的路由,几乎与整个应用程序行为无关。但是,对于大多数应用程序,我想在受限区域下隐藏新的简单snaplet,只有登录的用户才能进入。
对于root snaplet,问题通过使用简单函数restricted
解决,该函数接受处理程序并检查用户是否已登录,继续执行给定处理程序或重定向到登录屏幕。
以下是整个配置:
appInit :: SnapletInit App App
appInit = makeSnaplet "myapp" "My Example Application" Nothing $ do
fs <- nestSnaplet "foo" foo fooInit
ss <- nestSnaplet "sess" sess $
initCookieSessionManager "site_key.txt" "sess" (Just 3600)
as <- nestSnaplet "auth" auth $
initJsonFileAuthManager defAuthSettings sess "users.json"
addRoutes [("content", restricted $ render "content"),
("login", login)]
return $ App ss as fs
restricted :: Handler App App () -> Handler App App ()
restricted = requireUser auth (redirect "/login")
fooInit :: SnapletInit b Foo
fooInit = makeSnaplet "foo" "A nested snaplet" Nothing $ do
addRoutes [("info", writeText "Only registered users can have acess to it")]
return Foo
如果我输入http://mywebsite/foo/info,我将能够在不登录的情况下查看子包的内容。在我看来,我无法保护在我的新Foo
内部实现的所有处理程序,而无需更改该snaplet并修改其路由。或者我错了吗?
PS:有一个选项可以使用weapSite
并检查请求网址,但由于它意味着基于网址的验证,而不是追索权,(在这种情况下为处理程序)对我来说似乎不对。
答案 0 :(得分:1)
这里的答案是使用wrapSite
function。它需要一个参数(Handler b v () -> Handler b v ())
,它正是您restricted
函数的类型签名。