Open10

supabase DB 権限

プログラミングをするパンダプログラミングをするパンダ

auth スキーマには誰もアクセスできないようにされている。

ユーザーに紐づくデータをテーブルに格納したい場合は、以下のように ID を外部キーにする

create table public.profiles (
  id uuid references auth.users not null,
  first_name text,
  last_name text,

  primary key (id)
);

alter table public.profiles enable row level security;
プログラミングをするパンダプログラミングをするパンダ

しかし、以下のように API を利用してもデータは返ってこない

const { data } = await supabase
  .from('profiles')
  .select('id, first_name, last_name')

console.log(data) // []

これは profiles テーブルにrow level security(RLS)を設定しているため。

プログラミングをするパンダプログラミングをするパンダ

そこで、policy を設定してテーブルからデータを取得できるようにする。そのパターンはPublic AccessとPrivate Accessの2つある

  1. 誰でも読み取れるが、更新はそのデータに紐づいたユーザーしかできない(Public Access)
  2. ユーザーは自分自身に紐づくデータのみ読み取れるが、更新はできない(Private Access)
create table public.profiles (
  id uuid references auth.users not null,
  first_name text,
  last_name text,

  primary key (id)
);

alter table public.profiles enable row level security;
  • id の型は varchar ではなく uuid
プログラミングをするパンダプログラミングをするパンダ

Public Accessは以下のように設定する

create policy "Public profiles are viewable by everyone."
  on profiles for select
  using ( true );

create policy "Users can insert their own profile."
  on profiles for insert
  with check ( auth.uid() = id );

create policy "Users can update own profile."
  on profiles for update
  using ( auth.uid() = id );

こんな感じ

create policy "ポリシー名"
  on テーブル名 for 操作(select/insert/updateusing ( 条件式 );
プログラミングをするパンダプログラミングをするパンダ

ログインしないとデータが取れない

// This will return nothing while the user is logged out
const { data } = await supabase
  .from('profiles')
  .select('id, username, avatar_url, website')

// After the user is logged in, this will only return 
// the logged-in user's data - in this case a single row
const { error } = await supabase.auth.signIn({ email })
const { data: profile } = await supabase
  .from('profiles')
  .select('id, username, avatar_url, website')
プログラミングをするパンダプログラミングをするパンダ

ユーザーが sign すると users テーブルにデータが insert されるトリガー

create function public.handle_new_user() 
returns trigger 
language plpgsql 
security definer 
as $$
begin
  insert into public.users (id)
  values (new.id);
  return new;
end;
$$;

-- trigger the function every time a user is created
create trigger on_auth_user_created
  after insert on auth.users
  for each row execute procedure public.handle_new_user();