Open 3noch opened 7 years ago
BTW this extra header can be added by using clientWithOpts
.
Hi
We made this work using the Web.Cookie (cookie) library to parse the cookie text. The following example is based on a Servant authentication API derived from servant-auth-server
:
type Authenticated = Auth '[Cookie] User
type SetCookies = Headers '[ Header "Set-Cookie" SetCookie
, Header "Set-Cookie" SetCookie
] NoContent
type AuthApi
= "login" :> ReqBody '[JSON] LoginInfo :> PostNoContent '[JSON] SetCookies
:<|> Authenticated :> "user" :> Get '[JSON] User
This is the Servant.Reflex
code required to get the cookie, and put it into the request header:
-- Get the XHR-COOKIE if set
let getToken = lookup "XSRF-TOKEN" . parseCookiesText . T.encodeUtf8
xsrfToken <- liftJSM $ getToken <$> (currentDocumentUnchecked >>= getCookie)
-- API access functions
let tweakRequest = ClientOptions $ \r -> do
return $ r & xhrRequest_config
. xhrRequestConfig_headers
. at "X-XSRF-TOKEN" .~ xsrfToken
pm = Proxy :: Proxy m
pn = Proxy :: Proxy ()
bp = constDyn (BasePath "/")
login :<|> user = clientWithOpts api pm pn bp tweakRequest
@finlay Thanks for the full example! Is it possible to put the getToken
bit into tweakRequest
itself so you can derive these functions once and reuse them again for different tokens?
I think the issue is that the currentDocumentUnchecked
function needs the MonadJSM
context, which IO doesn't have.
And the ClientOptions
type wraps a function in IO
.
We could change the ClientOptions
type a little perhaps. @hamishmack was wondering about that.
F
There is a way to get the JSM context and regain it again but I can't recall how. I'm sure @hamishmack knows.
@finlay @3noch changing the type of ClentOptions
sounds promising.
servant-auth-server
by default expects that the [browser] client will add anX-XSRF-TOKEN
header with the contents of theXSRF-TOKEN
cookie for authenticated requests. I have a PR servant-auth to make this configurable, but regardless it would be nice if servant-reflex made this easier. Now that we have #47, we can actually do this manually. In fact, that may be the only way currently. The reason is that servant-auth doesn't "advertise" in the types the name of the XSRF cookie or the header it expects. The server and the client need to negotiate that out-of-band (so to speak).Thoughts?