nuxt-modules / supabase

Supabase module for Nuxt.
https://supabase.nuxtjs.org
MIT License
680 stars 124 forks source link

Top level useFetch does not send Supabase authorization headers #135

Closed ymansurozer closed 1 year ago

ymansurozer commented 1 year ago

I am fetching data with a top level useFetch as below:

<script setup lang="ts">
...
const { data } = await useFetch("/api/data");
...
</script>

I am also checking in the backend if the user is authorized to send the request as below:

import { serverSupabaseUser } from "#supabase/server";

export default defineEventHandler(async event => {
  const user = await serverSupabaseUser(event);
  event.context.auth = { userId: user?.id };
});

event.context.auth.userId is set (so authorization headers are sent from useFetch) when I navigate between routes. But when I refresh/reload the page from the browser or just copy and paste the url to a new tab, event.context.auth.userId becomes undefined.

Is it possible to use top level useFetch to fetch data where authorization headers are sent? Or am I supposed to fetch the data in onMounted hook (which also works).

ymansurozer commented 1 year ago

I have some more context:

It seems when I try to get the serverSupabaseUser in a backend middleware, it returns undefined. But when I do the same in a backend api route, it works fine. Is this a bug maybe?

larbish commented 1 year ago

Could you try with:

const { data } = await useFetch('/api/data', {
  headers: useRequestHeaders(['cookie'])
})
ymansurozer commented 1 year ago

Ah, it works, thank you very much @larbish! So the issue is that I need to send the headers myself? Or is it only with useFetch and not $fetch? I am asking because not sending the headers manually sometimes works.

larbish commented 1 year ago

It works on browser side. When we call fetch in the browser, user headers like cookie will be directly sent to the API. But during server-side-rendering, since the fetch request takes place 'internally' within the server, it doesn't include the user's browser cookies, nor does it pass on cookies from the fetch response.

If you want more info, you can check: https://nuxt.com/docs/getting-started/data-fetching#isomorphic-fetch-and-fetch

azelalynetan commented 1 year ago

I'm using useFetch with headers and it was working before.

const { data } = await useFetch('/api/auth/user', {
  headers: useRequestHeaders(['cookie'])
})

But now, it returns null. I can't get the user using serverSupabaseUser from my api. I'm unsure if my recent Nuxt 3 release upgrade relates to this. Is this a new bug?

philliphartin commented 1 year ago

Same issue here, using Nuxt on a SPA mobile app, communicating with a Nuxt app running an API in the browser. Unable to get serverSupabaseUser to resolve the user