lookupSession“_ID”使用 Yesod / Haskell 进行身份验证时抛出错误

lookupSession "_ID" throws error using Yesod / Haskell for authentication

我的 chat.hamlet 文件中有以下内容,我想在用户登录时显示它,我们有一个 maybeAuthId.

<div style="float:left">
    $maybe _ <- maid
        <p>Your current auth ID: #{show maid}
        <h3>
            <a href=@{AuthR LogoutR}>Logout
    $nothing
        <h3>
            <a href=@{AuthR LoginR}>Register / Login
<br clear="all"/>

我试图定义 maybeAuthId = lookupSession "_ID" 但出现类型错误:

Couldn't match type ‘Key User’ with ‘Text’
    Expected type: HandlerT App IO (Maybe (AuthId App))
      Actual type: HandlerT App IO (Maybe Text)
    In the expression: lookupSession "_ID"
    In an equation for ‘maybeAuthId’: maybeAuthId = lookupSession "_ID"

相关代码如下:

instance YesodAuth App where
    type AuthId App = UserId

    loginDest _ = HomeR
    logoutDest _ = HomeR
    authPlugins _ = [ authBrowserId def
        , authGoogleEmail clientId clientSecret
        , authEmail
        ]

    -- Need to find the UserId for the given email address.
    -- Take it from database
    getAuthId creds = runDB $ do
        x <- insertBy $ User (credsIdent creds) Nothing Nothing False
        return $ Just $
            case x of
                Left (Entity userid _) -> userid -- newly added user
                Right userid -> userid -- existing user

    authHttpManager = httpManager

    maybeAuthId = lookupSession "_ID"

我该如何解决这个错误?

我认为您根本不应该设置 maybeAuthId。有一个 default one 具有相当多的额外逻辑,可以将返回的 Text 转换为正确的 AuthId:

-- | Retrieves user credentials from the session, if user is authenticated.
--
-- This function does /not/ confirm that the credentials are valid, see
-- 'maybeAuthIdRaw' for more information.
--
-- Since 1.1.2
defaultMaybeAuthId
    :: (YesodAuthPersist master, Typeable (AuthEntity master))
    => HandlerT master IO (Maybe (AuthId master))
defaultMaybeAuthId = runMaybeT $ do
    s   <- MaybeT $ lookupSession credsKey
    aid <- MaybeT $ return $ fromPathPiece s
    _   <- MaybeT $ cachedAuth aid
    return aid

如果您不设置 maybeAuthId,则将使用此默认实现。