Haskell Snap:使用CSRF检查器包装身份验证处理程序

Haskell Snap:使用CSRF检查器包装身份验证处理程序,haskell,haskell-snap-framework,Haskell,Haskell Snap Framework,我有以下处理程序,用于检查给定处理程序的授权: needsAuth :: Handler App (AuthManager App) () -> Handler App App () needsAuth x = with auth $ requireUser auth noUserHandler x where noUserHandler = handleLogin (Just "must be logged in") 在Site.h中,我指定了如下路径:(“/trans

我有以下处理程序,用于检查给定处理程序的授权:

  needsAuth :: Handler App (AuthManager App) () -> Handler App App ()
  needsAuth x = with auth $ requireUser auth noUserHandler x
    where noUserHandler = handleLogin (Just "must be logged in")
Site.h
中,我指定了如下路径:
(“/transfers”,needsAuth handleTransfers)
其中handleTransfers的签名是
handleTransfers::Handler App(AuthManager App)(

在我的应用程序中,只有少数处理程序具有用户提交的表单;我想对它们使用CSRF检查,我认为用CSRF检查处理程序包装授权处理程序会很方便,因此我可以将路由更改为如下内容:

("/test", handleCSRF $ needsAuth handleTest)
基于snap extras软件包中的想法,我创建了函数handleCSRF:

handleCSRF :: Handler b v () -> Handler b v ()
handleCSRF x = do
  m <- getsRequest rqMethod
  if m /= POST
    then x
    else do tok <- getParam "_csrf"
          s <- gets session
          realTok <- withSession s csrfToken
          if tok == Just (E.encodeUtf8 realTok)
            then x
            else writeText $ "CSRF error"
我正在初始化会话snaplet,如下所示:

   s <- nestSnaplet "sess" sess $
       initCookieSessionManager "site_key.txt" "sess" (Just 1200)
s试试这个:

handleCSRF :: Handler App App () -> Handler App App ()
handleCSRF x = do
  m <- getsRequest rqMethod
  if m /= POST
    then x
    else do tok <- getParam "_csrf"
          realTok <- withSession sess csrfToken
          if tok == Just (E.encodeUtf8 realTok)
            then x
            else writeText $ "CSRF error"
handleCSRF::Handler-App-App()->Handler-App-App()
handleCSRF x=do

m谢谢,我本来试过了,但是在'withSession'的第一个参数中,即'do'块的stmt中的'session':realTok中,我遇到了一些错误,如
Expected type:SnapletLens b SessionManager实际类型:AuthManager b0->SnapletLens b0 SessionManager。我需要查看有关应用程序类型的更多信息。听起来你实际上并没有做任何镜头。按照这里看到的例子。嗨@mightybyte,我在上面添加了一些关于应用类型的附加信息。我还尝试将带有session session的
行更改为带有session sess的
行,这似乎让我更接近,但开始给我一些错误,如
预期类型:Handler App T.Text实际类型:Handler App SessionManager T.Text
。是的,
带有session sess
。我对上面的答案进行了编辑,以使其更具体。我没有足够的信息来调试您的新错误。我很确定这应该是正确的。我猜问题出在你的csrfToken函数中。感觉我们非常接近!剩下的一个错误:
无法将类型“SessionManager”与“App”匹配预期类型:Handler App t.Text实际类型:Handler App SessionManager t.Text在
withSession的第二个参数中,即“do”块的stmt中的“csrfToken”:realTok
   s <- nestSnaplet "sess" sess $
       initCookieSessionManager "site_key.txt" "sess" (Just 1200)
handleCSRF :: Handler App App () -> Handler App App ()
handleCSRF x = do
  m <- getsRequest rqMethod
  if m /= POST
    then x
    else do tok <- getParam "_csrf"
          realTok <- withSession sess csrfToken
          if tok == Just (E.encodeUtf8 realTok)
            then x
            else writeText $ "CSRF error"