1

So I enable RLS by using the template and trying to limit access to only logged in user

CREATE POLICY "Enable read access for authenticated users" ON "public"."item"
AS PERMISSIVE FOR SELECT
TO authenticated
USING (true)
A supabase client is like so

// utils.js

export function supabaseClient(options, token) {
  const options = {
    ...options,
    schema: schema || 'public',
    global: {
      headers: {
        Authorization: `Bearer ${token}`,
      },
    },
  };

  return createClient(
    process.env.NX_SUPABASE_URL,
    process.env.NX_SUPABASE_ANON_KEY,
    // process.env.NX_SUPABASE_SERVICE_ROLE_KEY,
    options
  );
}

// component,js

const supabase = supabaseClient(options);
const { count, error: errorCount } = await supabase
  .from('item')
  .select(*);

After a successful login, I pass the token to supabase client and the token is present on the options object. The issue is the data empty and no error.

If I add the anon role like so, the data is present but I don't want that behavior

CREATE POLICY "Enable read access for authenticated users" ON "public"."item"
AS PERMISSIVE FOR SELECT
TO authenticated, anon
USING (true)

So how can I limit access to the table with ANON_KEY and access_token to only authenticated user only? I search on the doc but nothing I can find useful

Eko Andri
  • 181
  • 2
  • 5
  • 17

1 Answers1

2

No need to make things complicated. Supabase will add the appropriate access token for you in the background once you login, so don't try to manage it by yourself.

// get rid of the token parameter
export function supabaseClient(options) {
  const options = {
    ...options,
    schema: schema || 'public',
  };

  return createClient(
    process.env.NX_SUPABASE_URL,
    process.env.NX_SUPABASE_ANON_KEY,
    // process.env.NX_SUPABASE_SERVICE_ROLE_KEY,
    options
  );
}

Then you should be able to do the following

// get a reference to the supabase client
const supabase = supabaseClient(options);

// sign in
await supabase.signInWithPassword({email: 'my-email@example.com', password: 'secure_password'})

// get data as a signed in user
const { count, error: errorCount } = await supabase
  .from('item')
  .select(*);
dshukertjr
  • 15,244
  • 11
  • 57
  • 94
  • Thanks this works! I think I followed the tutorial on youtube about next auth with supabase adapter that's why I add the token there. Also, can you advise, if I move the function for supabase client to api pages on NextJs, it doesnt work Can you advise how to achieve that? Thanks – Eko Andri Jan 25 '23 at 07:22
  • Has to clarify since I can't edit the comment above: "if I call the function for supabase client from api pages on NextJs, the data is empty and no error." – Eko Andri Jan 25 '23 at 07:29
  • 1
    @EkoAndri For the API routes, the typical way to go is to use the service role key. https://github.com/supabase/supabase/discussions/1284 Creating a Supabase client with service role key allows you to bypass RLS and access any data on your database. – dshukertjr Jan 25 '23 at 07:32
  • Would it still possible to limit some role using service key? – Eko Andri Jan 25 '23 at 07:45
  • @EkoAndri Before answering that, why are you using the API routes in the first place? Why not just query the data from the client side? – dshukertjr Jan 25 '23 at 07:47
  • I want to secure the payload and the data response so it's not 'visible' in the network tab when in production mode by hashing the payload and the data response – Eko Andri Jan 25 '23 at 07:50
  • Here is the sample code https://github.com/techandmedia/dbeuh/blob/feature/adding-supabase-example/apps/next-antd-v5/pages/api/supabase.ts – Eko Andri Jan 25 '23 at 07:52
  • 1
    @EkoAndri That is security through obscurity, and you shouldn't do it. https://en.wikipedia.org/wiki/Security_through_obscurity Data is transferred over TSL connection, so attackers cannot view the data, and the client can see the data anyway if it's being decrypted on the client side, so encrypting the data on the API route has no added security. Just query the data from client side. – dshukertjr Jan 25 '23 at 07:56
  • Noted on the suggestion. So the best way is using anon key from the client side – Eko Andri Jan 25 '23 at 07:59
  • @EkoAndri Yup! As long as you have the proper RLS policies set on the tables, that is super secure. – dshukertjr Jan 25 '23 at 08:08