代码之家  ›  专栏  ›  技术社区  ›  Marc

getAuthEntity失败“无法匹配预期类型”

  •  0
  • Marc  · 技术社区  · 6 年前

    我正在尝试向Yesod添加硬编码身份验证。我刚刚简单地修改了Yesod脚手架,并按照文档添加了一个硬编码用户( http://hackage.haskell.org/package/yesod-auth-1.6.3/docs/Yesod-Auth-Hardcoded.html ).所以我有以下代码:

    instance YesodAuth App where
        type AuthId App = Either UserId Text
    
        -- Where to send a user after successful login
        loginDest :: App -> Route App
        loginDest _ = HomeR
        -- Where to send a user after logout
        logoutDest :: App -> Route App
        logoutDest _ = HomeR
        -- Override the above two destinations when a Referer: header is present
        redirectToReferer :: App -> Bool
        redirectToReferer _ = True
    
        authPlugins _ = [authHardcoded]
    
        authenticate Creds{..} =
            return
            (case credsPlugin of
                "hardcoded" ->
                    case lookupUser credsIdent of
                        Nothing -> UserError InvalidLogin
                        Just m  -> Authenticated (Right (manUserName m)))
    
    
    -- | Access function to determine if a user is logged in.
    isAuthenticated :: Handler AuthResult
    isAuthenticated = do
        muid <- maybeAuthId
        return $ case muid of
            Nothing -> Unauthorized "You must login to access this page"
            Just _ -> Authorized
    
    
    ...        
    
    instance YesodAuthPersist App where
        type AuthEntity App = Either User SiteManager
    
        getAuthEntity (Left uid) =
          do x <- liftHandler $ runDB (get uid)
             return (fmap Left x)
        getAuthEntity (Right username) = return (fmap Right (lookupUser username))
    ...
    instance PathPiece (Either UserId Text) where
        fromPathPiece = readMaybe . unpack
        toPathPiece = pack . show
    
    lookupUser :: Text -> Maybe SiteManager
    lookupUser username = find (\m -> manUserName m == username) siteManagers
    
    instance YesodAuthHardcoded App where
        validatePassword u = return . validPassword u
        doesUserNameExist  = return . isJust . lookupUser
    
    validPassword :: Text -> Text -> Bool
    validPassword u p =
        case find (\m -> manUserName m == u && manPassWord m == p) siteManagers of
            Just _ -> True
            _      -> False
    

    因此,getAuthEntity似乎已经得到了正确的实现。然而,现在当我尝试使用getAuthEntity获取用户时,如下所示:

    getProfileR :: Handler Html
    getProfileR = do
        uid <- getAuthEntity   
        defaultLayout $ do
            setTitle . toHtml $ ("hola" :: Text )
            $(widgetFile "profile")
    

    它只会失败,并出现以下错误:

        • Couldn't match expected type ‘HandlerFor App a0’
                      with actual type ‘AuthId (HandlerSite m0)
                                        -> m0 (Maybe (AuthEntity (HandlerSite m0)))’
       |
    12 |     uid <- getAuthEntity
       |            ^^^^^^^^^^^^^
    

    我完全不知道会出什么问题。提前感谢您的帮助。

    1 回复  |  直到 6 年前
        1
  •  2
  •   Marc    6 年前

    好的,所以我设法解决了这个问题,正如你不能打电话的评论所指出的 getAuthEntity 但您也需要用户。所以我将代码改为

    getProfileR :: Handler Html
    getProfileR = do
        uid <- requireAuthId  
        user <- getAuthEntity uid 
    
        defaultLayout $ do
            -- setTitle . toHtml $ userIdent user <> "'s User page"
            setTitle . toHtml $ ("hola" :: Text )
            $(widgetFile "profile")
    

    然后它工作了,但是使用 maybeAuthId 而不是 requireAuthId 将给出一个错误。至于为什么我还不确定。

    推荐文章