How to include credentials in fetch/preload with Svelte/Sapper?

Viewed 1437

Setup

I have a typical web app setup:

  • A backend service running at https://mybackendsvc.com
  • Users are authenticated with mybackendsvc.com, and have a session cookie.
  • Svelte/Sapper running at https://myfrontend.com

I'm using Sapper preload to fetch some data from https://mybackendsvc.com. Here's routes/mydata/[id].svelte:

<script context="module">
  export async function preload(page, session) {
    const res = await this.fetch(
      `https://mybackendsvc.com/api/public/${page.params.id}`,
      {
        credentials: 'include' // sends the session cookie to mybackendsvc.com
      }
    );
    if (res.status == 200) {
      let myData = await res.json();
      return { myData };
    } else if (res.status === 401) {
      this.error(401, "Unauthorized");
    } else {
      this.error(500, "Something went wrong");
    }
  }
</script>

<script>
  export let myData;
</script>

<div>
  {myData}
</div>

Note the use of fetch with credentials included:

{
  credentials: 'include'
}

The problem: Where "preload" executes matters

If a user navigates to mydata/[id] directly, preload runs on the node server, Sapper doesn't include the user's session cookie (likely because the node server doesn't have access to it), so mybackendsvc.com responds with 401. However if a user navigates to mydata/[id] via a link inside my app, preload is run browser-side, the browser includes the session cookie, and the call succeeds.

How can I make Sapper guarantee that fetch includes credentials in an api call? Or can you not use preload with authenticated API calls, only public API calls?

0 Answers
Related