supabase
supabase copied to clipboard
serverSupabaseUser not working on server route when app is deployed to Netlify.
Version
@nuxtjs/supabase: "^0.1.25" nuxt: "^3.0.0-rc.11"
Issue
I'm trying to deploy my Nuxt 3 app which renders client side to Netlify and locally, Supabase Auth works as intended.
However, upon deploying the app to Netlify, when I call server routes that needs user validation, suddenly the serverSupabaseUser returns undefined even though the user is logged in since a session was obtained from Supabase.
I'm wondering whether I did something wrong on my end or if I'm missing something.
nuxt.config.js
import { defineNuxtConfig } from 'nuxt/config';
export default defineNuxtConfig({
ssr: false,
target: 'static',
modules: [
'@nuxtjs/supabase',
...
],
...
});
server/api/profile.get.js
import { serverSupabaseUser } from '#supabase/server';
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
export default defineEventHandler(async (event) => {
const user = await serverSupabaseUser(event);
if (!user) {
throw new Error('Not authorized');
}
const profile = await prisma.profiles.findUnique({
where: {
id: user.id,
},
});
return profile;
});
pages/login.vue
async function login() {
const { error } = await client.auth.signIn({
email: email.value,
password: password.value,
initialCache: false,
});
if (error) $toast(error.message, 'error');
$toast('Successfully logged in!', 'success');
const { data: profile } = await useFetch('/api/profile');
store.setProfile(profile.value);
}
Fetch result:
Any help provided will be appreciated. Thanks!
Could you check if the correct headers are sent to the API endpoint when deployed?
On running netlify dev
locally, I see the sb-access-token
included in the request header.
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Cookie: sb-access-token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNjYzODcwMjQ2LCJzdWIiOiI2MGM3YjI0ZC0wOTE5LTQwYTctOWQwYy1jYTI4ZWU5ZGJlOTEiLCJlbWFpbCI6Imx1emFkYWphcnJlZEBnbWFpbC5jb20iLCJwaG9uZSI6IiIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6ImVtYWlsIiwicHJvdmlkZXJzIjpbImVtYWlsIl19LCJ1c2VyX21ldGFkYXRhIjp7fSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJzZXNzaW9uX2lkIjoiNGE4MWVmNDAtNWU4MS00N2NkLThiNjItMDU4ODZkMGVlMWFhIn0.Gs9EtBQV5JKNgeJ249HmdTIjB4ZyYKNvA-mPFb6qSxs
Host: localhost:8888
If-None-Match: W/"2f8-ja+LhF5HQLhq4kdO7AmNYEEC5Vc"
Referer: http://localhost:8888/transactions
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="104", "Opera GX";v="90"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36 OPR/90.0.4480.100
However, it isn't there on the deployed app.
:authority: thryft.netlify.app
:method: GET
:path: /api/users
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
referer: https://thryft.netlify.app/transactions
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="104", "Opera GX";v="90"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-origin
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36 OPR/90.0.4480.100
I've also noticed that even my auth middleware doesn't work as intended as after reloading the page, the user will be redirected back to the login page.
middleware/auth.js
export default defineNuxtRouteMiddleware(async (to) => {
const user = useSupabaseUser();
if (to.path === '/login' || to.path === '/signup') {
if (!user.value) {
return;
}
return '/';
}
if (!user.value) {
return '/login';
}
});
I think I figured out the problem. It really is on the sb-access-token
cookie that's missing from the request header. I tried copying the access token I got in my local development to the deployment site and the route guard and request guard works as intended!
However, is there any way to configure this so that Supabase will pass the appropriate cookies back to the Deployed app at Netlify?
This might be the solution: https://v3.nuxtjs.org/getting-started/data-fetching#example-pass-client-headers-to-the-api
Edit: not sure since it is for SSR…
I'm getting the same issue. It works on localhost but not when I deploy to Netlify. The sb-access-token field is not set in my cookies but I can see the access token in my localstorage. So I agree with @ninjaaaaah that the sb-access-token doesnt appear to be set. But again, works on localhost, just not when I deploy it to Netlify
EDIT: I got it to work as expected if I set the "sb-access-token" after a user logs in manually using useCookie() in Nuxt and pulling the access token from the session when the page is loaded but this feels super hacky.
Another dev and I were collaborating and he had a great point - the sb-access-token is being set with attributes HttpOnly and Secure, but there’s no SameSite attribute so it’s defaulting to “Lax”. Because of this plus the cookie coming from a different domain (supabase), the cookie is not being set at all. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite#lax
Is there anyway to set the cookie on the library side using the onAuthStateChange function? Just a thought but yall probably know better than me
You can use the supabase.client
option in the nuxt.config
: https://supabase.nuxtjs.org/get-started#client
See the available options: https://github.com/supabase/supabase-js/blob/master/src/lib/types.ts
You have cookieOptions
or maybe try localStorage
?
Indeed, I've reproduced it here: https://github.com/larbish/nuxt3-supabase-with-server-routes. Don't know what's going on with Netlify, need to dig into it. However, as a temporary fix you can deploy on Vercel as it is working as expected, you can check it here: https://nuxt3-supabase-with-server-routes-6ki7.vercel.app
Weird; thanks for the workaround. I've got it working by manually setting the cookie when a user logs in using the onAuthStateChange function in a plugin for now, and it seems to work.
Closing in favor of #101 (merging all Netlify issues)