Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

endpoints.xhr.Endpoints offers to no way to set withCredentials in the XMLHttpRequest #404

Open
esarbe opened this issue Nov 19, 2019 · 4 comments

Comments

@esarbe
Copy link

esarbe commented Nov 19, 2019

To be able to use cookies or authentication headers for cross-site requests, the XMLHttpRequest.withCredentials property must be set.

See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials

Alas, endpoints.xhr.Endpoints offers no way to set this.

@esarbe esarbe changed the title endpoints.xhr.Endpoints offers to no way to set withCredentials in the XMLHttpRequest` endpoints.xhr.Endpoints offers to no way to set withCredentials in the XMLHttpRequest Nov 19, 2019
@julienrf
Copy link
Member

I am not sure if we should add an option to the xhr.Endpoints interpreter that would set this flag for every request or if this is a setting you want to define per endpoint and that needs to be taken into account by both the server and the client.

The important question here is “should it (the fact that we need to set the withCredentials property) be part of the endpoint description or not?”. Being part of the endpoint description means that clients, server and documentations can leverage this information (for instance, the server interpreter could use this information to accordingly set-up the Access-Control-Allow-Origin response header).

@esarbe
Copy link
Author

esarbe commented Nov 19, 2019

I'm not convinced that it (the fact that we need to set the withCredentials property) it should be part of the endpoint description. It's pretty much independent from the service description, depending on the implicit knowledge that there is a cookie/header involved and that the request is cross-origin.

I guess it could be part of the service description, but that would require some kind of dedicated authentication/authorization language/algebra...?

@julienrf
Copy link
Member

julienrf commented Nov 19, 2019

I guess it could be part of the service description, but that would require some kind of dedicated authentication/authorization language/algebra...?

Yes, but so far we don’t have the concept of response headers, which means that you’d have to write an Endpoint constructor:

trait Cors extends endpoints.algebra.Endpoints {
  def corsEndpoint[A, B](
    origin: String,
    request: Request[A],
    response: Response[B]
  ): Endpoint[A, B]
}

And then implement it on server interpreters to set the Access-Control-Allow-Origin response header to the origin value, and implement it on client interpreters to set the withCredentials property to true.

That being said, if you’re not convinced that it should be part of the endpoint description, you could just specialize the xhr.Endpoints interpreter to set the withCredentials property:

trait CorsEndpoints extends xhr.Endpoints {
  override def request[A, B, C, AB, Out](
    method: Method,
    url: Url[A],
    entity: RequestEntity[B],
    docs: Documentation,
    headers: RequestHeaders[C]
  )(implicit tuplerAB: Tupler.Aux[A, B, AB], tuplerABC: Tupler.Aux[AB, C, Out]): Request[Out] =
    new Request[Out] {
      def apply(abc: Out) = {
        val (ab, c) = tuplerABC.unapply(abc)
        val (a, b) = tuplerAB.unapply(ab)
        val xhr = makeXhr(method, url, a, headers, c)
        xhr.withCredentials = true
        (xhr, Some(entity(b, xhr)))
      }

      def href(abc: Out) = {
        val (ab, _) = tuplerABC.unapply(abc)
        val (a, _) = tuplerAB.unapply(ab)
        url.encode(a)
      }
    }
}

And then mix CorsEndpoints to your client implementation. (but eventually, we should add an option for that in endpoints so that you wouldn’t need to override the request constructor).

@esarbe
Copy link
Author

esarbe commented Nov 25, 2019

I've now used a second-ish approach to solve my particular problem; thus far it works, which is nice.

I however still don't have a clear understanding whether or not this is part of the endpoint description. If I look at i.e. http4s this seems to be a separate concern.

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

No branches or pull requests

2 participants