在单个POST请求中如何使用Snap的身份验证机制?

时间:2014-06-21 15:22:01

标签: authentication haskell haskell-snap-framework

我正在使用基于Haskell Snap的Web应用程序,我希望公开一个将由远程服务调用的API端点,而无需事先建立经过身份验证的会话;但是,我确实希望对该请求进行身份验证,因此应在请求时提供凭据。

您可以想象包含四个字段的请求:

  • 用户名
  • 密码
  • 有效负载ID
  • 有效负载文件

有效负载ID和文件可能与此问题无关,但我包含它们是因为我(a)需要支持此请求中的文件上传(据我所知,它限制用于发送字段的编码)和( b)需要检索至少一个非文件字段。

,当我在没有认证的情况下进行设置时,这些事情的组合会带来一些困难

按照Snap的说法,让我们调用此处理程序uploadHandler

如上所述,我在没有身份验证的情况下工作正常,设置如下:

uploadHandler :: Handler App App ()
uploadHandler = do
  -- collect files / form fields and process as needed.

-- and using the routes:
routes :: [(ByteString, Handler App App ())]
routes = [ ("/login",    with auth handleLoginSubmit)
         , ("/logout",   with auth handleLogout)
         , ("/new_user", with auth handleNewUser)

         -- handle the upload:
         , ("/upload",   handleUpload)
         ]

天真的解决方案是简单地添加' auth'并更改handleUpload的类型:

uploadHandler :: Handler App (AuthManager App) ()
uploadHandler = do
  -- collect files / form fields and process as needed.

-- and using the routes:
routes :: [(ByteString, Handler App App ())]
routes = [ ("/login",    with auth handleLoginSubmit)
         , ("/logout",   with auth handleLogout)
         , ("/new_user", with auth handleNewUser)

         -- handle the upload, with auth:
         , ("/upload",   with auth handleUpload)
         ]

但是,这似乎需要两个请求:(i)验证并建立会话,(ii)发送包含实际有效载荷的POST请求。

我找到了一种在一个请求中执行此操作的方法,但似乎应该有更优雅的方法。这是我一起被黑客攻击的示例限制POST处理程序:

restrictedPOST :: Handler App (AuthManager App) ()
restrictedPOST = do
  mName <- getPostParam "username"
  mPass <- getPostParam "password"
  let uName = C8.unpack $ fromMaybe "" mName
      pass = ClearText $ fromMaybe "" mPass

  authResult <- loginByUsername (T.pack uName) pass False
  case authResult of
    Left authFail -> writeText "Could not log in"
    Right user    -> writeText (T.append "Hello " (userLogin user))

是否有类似&#39;与auth&#39;我可以使用而不是将此示例(restrictedPOST)转换为组合器?我意识到它可能需要知道哪些字段可以获取凭证,但我对网络服务知之甚少(也许还有其他方法?也许这完全没有问题,我只是不知道如何检查auth是否有POST请求。我可以接受任何建议!)

1 个答案:

答案 0 :(得分:1)

我不认为您了解with auth正在做什么。它与是否需要身份验证无关。它所做的就是将Handler b (AuthManager b)转换为Handler b v。没有执行权限检查。你的restrictedPOST函数有正确的想法。