2

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?

2 Answers2

1

Row Level Security (RLS) will fail if you are missing certain properties from your JWT. In your case you are probably using the auth.uid() function in your RLS which relies on a sub property for the user id. You need to add that to your JWT along with your existing userId property.

const payload = {
  userId: user.email,
  sub: user.id, // this must correspond with a user id in the table you are testing your RLS policy against
  exp: Math.floor(Date.now() / 1000) + 60 * 60,
}
const accessToken = jwt.sign(payload, SUPABASE_SECRET_KEY)
Andrew Smith
  • 1,224
  • 6
  • 9
1

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.