Search code examples
cookiescorshtmx

Why isn't there the cookie sent for cross domain request?


I have the following setup:

There is a haproxy running on port 443 using mkcert certificates. In the proxy the www request are sent to the static site engine the app requests are sent to the Rust backend.

use_backend www if { hdr(host) -i www.localhost.lan }
use_backend app if { hdr(host) -i app.localhost.lan }

The full config is here: https://gist.github.com/l1x/ab941cedecd85ba9a8b44046367e1d1a

When a user logs in we issue a cookie:

          let cookie = Cookie::build(("vs-jwt", &s))
                .domain(".localhost.lan")
                .secure(true)
                .same_site(SameSite::None)
                .http_only(true)
                .path("/")
                .max_age(Duration::WEEK)
                .build();

enter image description here

When I am navigating to www.localhost.lan/app the following happens:

Cookie sent:

enter image description here

Cookie not sent:

enter image description here

What am I missing?

I was trying to fiddle with the cookie settings but I think it should work. Does it matter if the request was initiated by JS (HTMX in this case)?

The code that is actually triggering the GET request:

<section class="bg-white dark:bg-gray-900">

    <div id="app">
    </div>

    <div hx-get="https://app.localhost.lan/view/app" hx-trigger="load" hx-target="#app">
      <img alt="Result loading..." class="htmx-indicator" width="150" src="/img/bars.svg" />
    </div>

  </section>

I have narrowed it down to HTMX. The standard request works:

const xhr = new XMLHttpRequest();
xhr.open("GET", "https://app.localhost.lan/view/app", true);
xhr.withCredentials = true;
xhr.send(null);

This sends the cookie.


Solution

  • As it turns out by default the AJAX requests do not send cookies.

    The default JS libs have the following:

    xhr.withCredentials = true;
    

    In HTMX this has to be configured as well:

     <div 
    hx-get="https://app.localhost.lan/view/app" 
    hx-request='{"credentials": true}' 
    hx-trigger="load"
    hx-target="#app">
          <img alt="Result loading..." 
          class="htmx-indicator" 
          width="150" src="/img/bars.svg" />
    </div>