Search code examples
supabasesupabase-database

Supabase realtime connection failing when custom JWT is used


I'm using supabase self-hosted and auth0 for my authentication instead of the default authentication provided by supabase. So I'm signing my auth0's payload with supabase secret and sending it in headers.

const payload = {
    userId: user.email,
    exp: Math.floor(Date.now() / 1000) + 60 * 60,
}
const accessToken = jwt.sign(payload, SUPABASE_SECRET_KEY)

const options = {}

if (accessToken) {
  options.global = {
    headers: {
      Authorization: `Bearer ${accessToken}`,
    },
  }
}
const supabase = createClient(supabaseUrl, supabaseAnonKey, options)
supabase.channel('custom-update-channel')
.on(
  'postgres_changes',
  { event: 'UPDATE', schema: 'public', table: 'user_notifications' },
  (payload) => { 
      console.log('Change received!', payload)
  }
)
.subscribe()

I also enabled the RLS policy on my table. Using the above headers I'm able to query my database. Now I wanted to enable real-time on my table. But when I try to create a subscription with my custom headers, the Realtime web socket connection throws an Authentication error. When I don't send the custom JWT in the header, it works fine but I need my custom JWT's payload to be stored in the subscription table. realtime so that I can use it on my RLS Policy. What should I do to fix this?


Solution

  • When you use self-hosted supabase, kong will allow only an anon key or service key to be passed as an API key. To set our custom token we can do something like this:

    const supabase = createClient(supabaseUrl, supabaseAnonKey, options)
    supabase.realtime.accessToken = 'custom jwt'
    

    Directly setting access token in realtime client.