Skip to content
This repository has been archived by the owner on Oct 29, 2021. It is now read-only.

Missing part in readme: Can't successfully use cookie from browser #166

Open
bratfizyk opened this issue Jul 14, 2020 · 2 comments
Open

Comments

@bratfizyk
Copy link

bratfizyk commented Jul 14, 2020

I've been trying to implement a very simple server with even simpler Lucid client that would work with Cookie auth server presented in this project's Readme. However, based on the information found there I'm unable to implement this.
The problem is that I always get "AuthResult Indefinite" instead of "Authenticated" even though I get the cookie and my browser manages to process it. I guess I must be missing a tiny part, but not sure which one.

I've got a simple api, as suggested in the tutorial:

data User = User String
    deriving (Eq, Show, Generic)

data Credentials = Credentials {
    credentialsUserName :: String,
    credentialsPassword :: String
} deriving (Eq, Show, Read, Generic)

type Unprotected =
    "logMe" :> Get '[HTML] (Html ())
    :<|> "login" 
            :> ReqBody '[FormUrlEncoded] Credentials 
            :> Verb 'POST 204 '[JSON] (Headers '[ Header "Set-Cookie" SetCookie, Header "Set-Cookie" SetCookie] NoContent)

type Protected
   = "name" :> Get '[JSON] String

type AuthAPI =
    (Servant.Auth.Server.Auth '[Cookie] User :> Protected)
    :<|> Unprotected

I added the "logMe" endpoint that contains a simple form that works with "Credentials" type. This part of code most likely works ok, as I get a cookie in my browser.
image

Then, when I try poking the "name" endpoint, I get "Indefinite" result. I guess my project is missing a part that does cookie to User conversion, but I'm not sure how to add this. Any hints ?

Other relevant pieces of my code (very similar to the content of Readme):

cookieConfig :: CookieSettings
cookieConfig = defaultCookieSettings { cookieIsSecure = NotSecure }

getJwtConfig :: IO JWTSettings
getJwtConfig = do
    key <- generateKey 
    return $ defaultJWTSettings key

context :: CookieSettings -> JWTSettings -> (Context '[CookieSettings, JWTSettings])
context cookieConfig jwtConfig = cookieConfig :. jwtConfig :. EmptyContext

protected :: Servant.Auth.Server.AuthResult User -> Server Protected
protected (Servant.Auth.Server.Authenticated (User name)) = return name
protected x = trace ("Access Denied " ++ (show x)) $ throwAll err401

checkCreds :: CookieSettings -> JWTSettings  -> Credentials 
                                -> Handler (Headers '[ Header "Set-Cookie" SetCookie, Header "Set-Cookie" SetCookie] NoContent)
checkCreds cookieSettings jwtSettings (Credentials { credentialsUserName = "Ali Baba", credentialsPassword = "Open Sesame"}) = do
    mApplyCookies <- liftIO $ acceptLogin cookieSettings jwtSettings (User "Ali Baba")
    case mApplyCookies of
        Nothing           -> trace "Nothing" $ throwError err401
        Just applyCookies -> return $ applyCookies NoContent
        
checkCreds _ _ (Credentials { credentialsUserName = user, credentialsPassword = _}) = 
    trace ("Received " ++ user)
        throwError err401

main :: IO ()
main = do
    migrateDB
    jwtConfig <- getJwtConfig
    putStrLn $ "Serving endpoint " ++ (show port)
    run port $ serveWithContext proxy (context cookieConfig jwtConfig) (appAPI cookieConfig jwtConfig)

Dislaimer: I'm quite new to Haskell, so it might be the case that I'm missing an important concept here.

@bratfizyk bratfizyk changed the title Can't successfully use cookie from browser Missing part in readme: Can't successfully use cookie from browser Jul 14, 2020
@domenkozar
Copy link
Collaborator

It's since XSRF also checks GET requests (terrible default). I recommend disabling XSRF and setting cookieSameSite setting to SameSiteStrict

@bratfizyk
Copy link
Author

bratfizyk commented Jul 15, 2020

I tried

cookieConfig :: CookieSettings
cookieConfig = defaultCookieSettings { cookieIsSecure = NotSecure, cookieSameSite = SameSiteStrict, cookieXsrfSetting = Nothing }

and it did the job, thanks.
Over the weekend I'll think about a few other features (e.g. how to delete a cookie to log user out) and will come up with a PR for the README file so that this use case becomes more obvious.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants