After successful logging in, servant-auth sets a JWT-Cookie
cookie in the response. The problem is, it also flags the cookie as HttpOnly
, which means I can't read the JWT in my single page app. My understanding is that this can be configured with the SetCookie datatype. I've been able to create my own custom SetCookie
by using defaultSetCookie { setCookieHttpOnly = False }
. How do I stuff it into the acceptLogin
function?
Here is my handler for logging in.
checkCreds :: CookieSettings
-> JWTSettings
-> LoginRequest
-> App (Headers '[ Header "Set-Cookie" SetCookie
, Header "Set-Cookie" SetCookie ]
NoContent)
checkCreds cookieSettings jwtSettings LoginRequest{email = email, rawPassword = rawPassword} = do
maybeUser <- logicForFetchingAndValidatingUser
-- What do I do with this mySetCookie?
let mySetCookie = defaultSetCookie { setCookieHttpOnly = False }
case maybeUser of
Just userView -> do
mApplyCookies <- liftIO $ acceptLogin cookieSettings jwtSettings userView
case mApplyCookies of
Nothing -> throwError err401
Just applyCookies -> return $ applyCookies NoContent
Nothing -> throwError err401
I've read the source of acceptLogin
and figured out it calls makeSessionCookie
and makeXsrfCookie
, then uses the results to create a function for adding headers. I did the same in my code, modyfing the result of makeSessionCookie
along the way:
checkCreds :: CookieSettings
-> JWTSettings
-> LoginRequest
-> App (Headers '[ Header "Set-Cookie" SetCookie
, Header "Set-Cookie" SetCookie]
NoContent)
checkCreds cookieSettings jwtSettings LoginRequest{email = email, rawPassword = rawPassword} = do
-- Usually you would ask a database for the user info. This is just a
-- regular servant handler, so you can follow your normal database access
-- patterns (including using 'enter').
maybeUser <- logicForFetchingAndValidatingUser
case maybeUser of
Just userView -> do
mSessionCookie <- liftIO $ makeSessionCookie cookieSettings jwtSettings userView
case mSessionCookie of
Nothing -> throwError err401
Just sessionCookie -> do
let modifiedSessionCookie = sessionCookie { setCookieHttpOnly = False, setCookieSecure = False }
xsrfCookie <- liftIO $ makeXsrfCookie cookieSettings
return $ (addHeader modifiedSessionCookie . addHeader xsrfCookie) NoContent
Nothing -> throwError err401