One Server

문서

접근 규칙

새 표가 왜 비어 보이는지. 이 플랫폼에서 가장 자주 틀리는 곳이라 먼저 읽으세요.

접근 규칙 (RLS)

가장 자주 틀리는 곳이에요. 오류 없이 빈 목록이 돌아와서 틀린 줄 몰라요.

반드시 알아야 하는 것

새 표는 접근 규칙이 켜진 채 만들어지고 규칙은 하나도 없어요. 규칙이 없으면 아무에게도 보이지 않아요. 오류가 아니라 빈 배열이 돌아와요.

create table notes (id uuid primary key default gen_random_uuid(), body text);
-- 지금 공개 키로 select 하면: []  (오류 아님)

역할 이름

프로젝트마다 달라요. 고정된 anon/authenticated가 아니에요. list_policies가 그 프로젝트의 실제 역할 이름 세 개를 알려줘요.

역할누구
<ref>_anon로그인하지 않은 사람
<ref>_authenticated로그인한 사람
<ref>_service_role서버. 규칙을 통째로 우회해요

Supabase에서 쓰던 SQL은 그대로 실행돼요(Supabase 이름 변환). run_sql, query_sql, apply_migrations, 콘솔 SQL 편집기, oneend db push에서 public., auth., storage.는 app_<ref>., auth_<ref>., stor_<ref>.로, to/from 뒤의 anon, authenticated, service_role은 이 프로젝트의 역할로 바꿔 실행해요. 이름을 가리키는 문자열('public.orders'::regclass, to_regclass('public.orders'), 'public'::regnamespace)의 스키마도 바꿔요. 바꾼 내용은 응답의 translated에 있어요. 그 밖의 문자열·주석과 직접 연결(psql)은 바꾸지 않아요. 모든 실행은 search_path가 app_<ref>, auth_<ref>, public, extensions인 채로 돌아서, 스키마를 붙이지 않은 create table orders·'orders'::regclass도 이 프로젝트의 것을 가리켜요.

흔한 규칙 세 가지

-- 누구나 읽을 수 있게
create policy "public read" on notes for select to <ref>_anon using (true);

-- 로그인한 본인 것만
create policy "own rows" on notes for all to <ref>_authenticated
  using (user_id = auth_<ref>.uid());

-- 로그인한 사람이 쓰되, 남의 이름으로는 못 쓰게
create policy "insert own" on notes for insert to <ref>_authenticated
  with check (user_id = auth_<ref>.uid());

using은 읽을 때, with check는 쓸 때 봐요. insert에 using만 걸면 아무도 못 써요.

확인하는 법

list_policies로 규칙을 보고, read_rows로 공개 키로 실제로 보이는지 확인하세요. 표나 규칙을 바꾼 뒤에는 get_advisors로 RLS가 꺼진 표, 누구나 쓸 수 있는 규칙 같은 문제를 확인하세요.

앱이 시작할 때마다 실행하는 SQL(Figma Make의 kv_store 같은)에서는 인덱스에 이름을 붙이고 if not exists를 쓰세요: create index if not exists kv_store_x_key_idx on kv_store_x (key text_pattern_ops);. 이름 없는 create index on …은 실행할 때마다 _idx1, _idx2… 같은 인덱스를 하나 더 만들고, 쓰기마다 그 모두를 갱신해요. get_advisors의 duplicate_index가 하나만 남기는 drop index를 함께 줘요.

규칙을 만들었는데도 비어 있으면 대개 역할 이름이 틀린 거예요.