본문으로 건너뛰기
블로그로
공개 가이드튜토리얼

Supabase로 첫 데이터베이스: 로그인 없는 폼 저장하기

공식 출처 5건 · 본문 하단 확인 섹션과 동일

로그인 없이 이름과 이메일만 받는 폼이라면, 서버를 직접 만들지 않고 Supabase 테이블 하나로 끝낼 수 있습니다. 2026년 9월 11일 기준 Supabase 행 수준 보안 문서는 "노출된 스키마에 RLS 없이 놓인 테이블은 권한을 가진 어떤 역할이든 읽고 쓸 수 있다"고 적습니다. 즉 테이블을 만드는 것보다 누가 무엇을 할 수 있는지 잠그는 순서가 중요합니다.

첫 홈페이지 만들기로 Next.js 페이지를 배포한 다음 단계입니다.

전체 순서

단계하는 일확인할 것
1Supabase 프로젝트 생성무료 한도와 일시 중지 조건
2테이블 생성public 스키마는 API로 노출됨
3RLS 켜기정책이 없으면 전부 차단
4익명 insert 정책 하나만 추가select 정책은 만들지 않음
5키 두 종류 구분브라우저에는 공개 키만
6Next.js에 연결환경 변수 이름 고정

1. 프로젝트를 만들기 전에 한도부터

요금 페이지는 확인일 기준 Free 플랜에 데이터베이스 500MB, 파일 저장 1GB, 월간 활성 사용자 50,000명, 활성 프로젝트 2개를 제시하고, 1주간 활동이 없으면 프로젝트가 일시 중지된다고 적습니다. 수치는 자주 바뀌므로 시작 전에 요금 페이지를 직접 여십시오.

2. 테이블 만들기

대시보드의 Table Editor로 만들어도 되고 SQL Editor에 직접 써도 됩니다. 테이블 문서의 예시를 따르면 기본형은 이렇습니다.

create table public.subscribers (
  id bigint generated by default as identity primary key,
  email text not null,
  created_at timestamptz default now()
);

같은 문서는 커스텀 스키마를 Data API로 쓰려면 따로 노출과 권한 부여가 필요하다고 적습니다. 처음에는 public에 두는 편이 단순합니다.

3. RLS를 켭니다

alter table public.subscribers enable row level security;

RLS 문서는 정책이 하나도 없으면 "공개 키로는 API를 통해 어떤 데이터에도 접근할 수 없다"고 적습니다. 켠 직후가 가장 안전한 상태입니다. 여기서 필요한 구멍만 하나씩 뚫습니다.

4. 익명 insert만 허용합니다

로그인 없는 구독 폼에 필요한 권한은 "새 행 추가" 하나입니다. 읽기는 필요 없습니다.

create policy "anon can subscribe" on public.subscribers
for insert
to anon
with check ( true );

to anon은 로그인하지 않은 요청을 뜻하고, with check는 새로 들어오는 행이 조건을 만족해야 한다는 뜻입니다. select 정책을 만들지 않으면 누구도 목록을 읽어 갈 수 없습니다. 구독자 명단은 대시보드에서 보면 됩니다.

5. 키 두 종류를 구분합니다

여기서 사고가 가장 많이 납니다. API 키 문서의 구분은 이렇습니다.

접두사어디에 두나
Publishable keysb_publishable_브라우저·앱·소스 코드에 노출해도 되는 공개 키
Secret keysb_secret_서버·API·Edge Function 등 백엔드에만

문서는 secret key가 모든 RLS 정책을 우회한다고 적고, 브라우저에서는 User-Agent 헤더를 보고 401을 돌려주어 동작하지 않는다고 설명합니다. 예전 이름인 anon·service_role JWT 키도 아직 쓰이지만, 같은 문서는 2026년 말까지 이 두 키를 폐기할 예정이라고 적습니다.

이 폼에 필요한 것은 publishable key 하나뿐입니다. secret key는 복사할 일이 없습니다.

6. Next.js에 연결하기

Next.js 퀵스타트npx create-next-app@latest my-app -e with-supabase 템플릿을 쓰면 @supabase/supabase-js@supabase/ssr이 함께 설치되고 클라이언트 파일도 만들어진다고 안내합니다. 환경 변수 이름은 다음 두 개입니다.

NEXT_PUBLIC_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY

NEXT_PUBLIC_ 접두사는 브라우저까지 값이 전달된다는 뜻입니다. 그래서 이 자리에 secret key를 넣으면 안 됩니다.

이미 만들어 둔 페이지에 붙인다면 Claude Code에 이렇게 지시할 수 있습니다.

Supabase에 subscribers 테이블(email, created_at)이 있고 익명 insert 정책만 켜져 있다.
이 프로젝트의 /subscribe 페이지에 이메일 한 칸짜리 폼을 만들어 줘.
- 키는 NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY 환경 변수만 쓴다
- secret key는 어떤 파일에도 넣지 않는다
- 성공/실패 메시지를 화면에 표시하고, 중복 이메일은 사용자에게 안내만 한다
- 저장된 목록을 조회하는 코드는 만들지 않는다

먼저 계획을 받아 보고 싶으면 /plan을 앞에 붙입니다.

배포 전 마지막 확인

  1. 대시보드에서 해당 테이블의 RLS가 켜져 있고 정책이 insert 하나인지 봅니다.
  2. 로그아웃 상태의 브라우저에서 폼을 제출하고, 대시보드에 행이 쌓이는지 확인합니다.
  3. 저장소에 sb_secret_로 시작하는 문자열이 없는지 확인합니다.
  4. .env.local이 버전 관리에서 제외돼 있는지 확인합니다.

다음 단계

출처와 확인 (2026-09-11)