'SvelteKit API requests with Axios JWT authentication

I am creating an app with a SvelteKit client and a Laravel API stack, but I am struggling to safely authenticate my client to my API. Ideally I want to store a JWT token in my cookies that I send with requests to the Laravel API with Axios.

So far I have the token stored in my cookies, but the part that I can't get working is getting the JWT token from my cookies so I can send it in my Authorization header. I tried getting the token from the cookies in the handle hook, which works, and then adding it to my Axios headers. But this only seems to work server-side and not client-side.

The API module I use to send requests

import axios from 'axios'

class Api {
  private headers: Record<string, string> = {
    Accept: 'application/json',
    'Content-Type': 'application/json',
    'X-Requested-With': 'XMLHttpRequest'
  }

  get axiosInstance() {
    return axios.create({
      baseURL: 'http://localhost:8000/api/',
      headers: this.headers
    })
  }

  get get() {
    return this.axiosInstance.get
  }

  get post() {
    return this.axiosInstance.post
  }

  get patch() {
    return this.axiosInstance.patch
  }

  setAuthorization(token: string): void {
    this.headers.Authorization = `Bearer ${token}`
  }
}

const api = new Api()

export default api

The handle hook

export const handle: Handle = async ({ event, resolve }) => {
  const cookies = cookie.parse(event.request.headers.get('cookie') || '')

  const response = await resolve(event)

  if (cookies.jwt) {
    api.setAuthorization(cookies.jwt)
  }

  return response
}

If I console log the Axios instance it does show the Authorization header, but it is not being send with the request.

I did get it working by storing the JWT token in local storage, but this is not ideal security wise.



Solution 1:[1]

Make sure the axios option withCredentials is set to true (you should probably add it as a default request option when creating the instance to avoid repetition, but you can pass it with individual requests as well if you prefer).

See Make Axios send cookies in its requests automatically for in-depth details.

Solution 2:[2]

I have found the issue, the cookie had the HttpOnly so the client had no access to the cookies. I solved this by simply removing the HttpOnly flag in my Set-Cookie header, which is not very safe, so any other methods of solving this issue are very welcome.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Thomas Hennes
Solution 2 PeterSH