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つある
- 誰でも読み取れるが、更新はそのデータに紐づいたユーザーしかできない(Public Access)
- ユーザーは自分自身に紐づくデータのみ読み取れるが、更新はできない(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/update)
using ( 条件式 );
Private Accessは以下のように設定する
create policy "Profiles are viewable by users who created them."
on profiles for select
using ( auth.uid() = id );
こんな感じ`
select でも IDで制限をかける
ログインしないとデータが取れない
// 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();
認証済ユーザーだけが insert できるポリシー
CREATE POLICY "policy_name"
ON public.users
FOR INSERT WITH CHECK (
auth.role() = 'authenticated'
);
ポリシーはSQLだけでなく画面からも作れる