이메일 + 비밀번호
Google 설정은 필요 없다. Supabase에서 이메일 로그인을 켜고 앱의 콜백 주소만 등록하면 시작할 수 있다.
프로덕션에서는 확인·재설정 메일을 안정적으로 보내기 위해 커스텀 SMTP가 필요하다.
처음에는 로그인 하나만 끝까지 성공시키자. JWT·MFA·Hooks의 세부 원리는 Auth 참고서에서 필요할 때 찾으면 된다
이메일 + 비밀번호
Google 설정은 필요 없다. Supabase에서 이메일 로그인을 켜고 앱의 콜백 주소만 등록하면 시작할 수 있다.
프로덕션에서는 확인·재설정 메일을 안정적으로 보내기 위해 커스텀 SMTP가 필요하다.
Google 로그인
Google Cloud에서 우리 앱을 OAuth 클라이언트로 등록해야 한다. 여기서 받은 Client ID와 Secret을 Supabase에 전달한다.
Supabase는 Google의 로그인 결과를 받아 자기 세션으로 바꾸고, 앱은 그 세션만 사용한다. 이 중개 구조는 keycloak 덱의 Identity Brokering과 같은 자리다.
둘을 동시에 제공해도 된다. 다만 처음부터 매직 링크·전화번호·익명·MFA까지 모두 켜지 말고, 한 방식의 가입 → 로그인 → 로그아웃 → 보호된 데이터 조회를 먼저 완성하는 편이 쉽다.
Google은 아무 사이트에나 사용자 로그인 결과를 보내면 안 된다. 그래서 Google Cloud에 **“이 웹 앱이 요청하며, 결과는 이 Supabase 주소로만 돌려보낸다”**고 등록한다. Supabase도 아무 웹 주소로 세션을 보내면 안 되므로 우리 앱의 callback 주소를 별도로 허용한다.
주소 두 개를 구분하는 것이 핵심이다.
| 등록하는 곳 | 등록할 주소 | 누가 누구에게 돌아가나 |
|---|---|---|
| Google Auth Platform → Clients | https://<project-ref>.supabase.co/auth/v1/callback | Google → Supabase Auth |
| Supabase Auth → URL Configuration | https://example.com/auth/callback | Supabase Auth → 우리 앱 |
| 장소 | 설정하거나 받는 것 | 왜 필요한가 | 주된 방법 |
|---|---|---|---|
| Google Auth Platform | Audience, Branding, 기본 scope, Web OAuth Client, Supabase callback | Google이 앱과 반환 주소를 신뢰하도록 | 콘솔에서 직접 |
| Supabase Auth | Site URL, Redirect URLs, Google Client ID / Secret | Google 결과를 Supabase 세션으로 바꾸고 허용된 앱으로만 반환 | 대시보드 또는 config push |
| Vercel | Supabase URL, publishable key | 배포된 앱이 Supabase 프로젝트를 찾도록 | 대시보드 또는 CLI |
| 앱 코드 | 로그인 버튼, /auth/callback, 세션 갱신, RLS | 로그인 시작과 code 교환, 실제 권한 판정 | 코드 |
gcloud가 꼭 필요한 것은 아니다. Google 공식 정책상 OAuth 클라이언트는 남용 방지를 위해
프로그램으로 생성하거나 수정할 수 없고 Google Cloud 콘솔을 사용해야 한다. gcloud는 프로젝트·IAM·API 같은
다른 Google Cloud 자원을 함께 관리할 때는 유용하지만, 이 한 단계의 대체재는 아니다.
예시는 다음 세 주소를 사용한다.
로컬 앱 origin: http://localhost:3000프로덕션 앱 origin: https://example.com프로덕션 callback: https://example.com/auth/callbackVercel 기본 도메인으로 먼저 시험할 수도 있지만, 프로덕션에서는 최종 커스텀 도메인을 기준으로 설정한다. 프리뷰 로그인이 필요하면 뒤에서 프리뷰 주소를 추가한다.
대시보드 Authentication → URL Configuration에서 설정한다.
Site URL:https://example.com
Redirect URLs:http://localhost:3000/auth/callbackhttps://example.com/auth/callbackhttps://*-myteam.vercel.app/** # 프리뷰 로그인이 필요할 때만redirectTo를 생략했을 때 돌아가는 기본 주소다이메일 로그인만 쓸 사람은 여기까지 한 뒤 4번으로 가면 된다.
Google Auth Platform → Branding / Audience / Data Access
앱 이름과 지원 이메일, 외부 또는 조직 내부 사용자를 정한다. 로그인만 필요하면
openid, email, profile 범위를 사용하고 Google Drive 같은 추가 권한은 요청하지 않는다.
Google Auth Platform → Clients → Create client
애플리케이션 유형은 Web application으로 만든다.
Authorized JavaScript origins:http://localhost:3000https://example.com
Authorized redirect URIs:https://<project-ref>.supabase.co/auth/v1/callback로컬 Supabase 스택까지 Google과 연결해 시험할 때만
http://127.0.0.1:54321/auth/v1/callback도 추가한다.
Client ID와 Client Secret을 Supabase에 입력
대시보드 Authentication → Sign In / Providers → Google에서 Google을 켜고 두 값을 넣는다. Secret은 코드, Git, 채팅에 붙여 넣지 않는다.
Google의 Audience 상태를 확인
개발 중에는 필요한 계정으로 실제 로그인을 시험한다. 공개 출시 전에는 대상 사용자, 브랜드 정보, 소유 도메인과 검증 상태를 다시 확인한다. 민감한 Google API scope를 추가하면 로그인만 할 때보다 별도의 검토가 필요할 수 있다.
Supabase 대시보드 Project Settings → API Keys에서 URL과 publishable key를 확인한다.
NEXT_PUBLIC_SUPABASE_URL=https://<project-ref>.supabase.coNEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=sb_publishable_...두 값은 브라우저에 노출되는 공개 식별자다. 그래도 데이터가 공개되는 것은 아니다.
실제 접근 권한은 RLS가 결정한다. 반대로 sb_secret_... 키에는 절대 NEXT_PUBLIC_을 붙이지 않는다.
Vercel CLI가 연결돼 있다면 대화형 입력으로 등록할 수 있다.
vercel loginvercel linkvercel env add NEXT_PUBLIC_SUPABASE_URL productionvercel env add NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY productionPreview와 Development에도 같은 프로젝트를 쓸 계획이라면 각 환경에 별도로 추가한다. PR마다 Supabase Preview Branch를 쓰는 구성은 12장에서 다룬다.
// Client Component의 클릭 핸들러await supabase.auth.signInWithOAuth({ provider: 'google', options: { redirectTo: `${location.origin}/auth/callback?next=%2Fme`, },})export async function GET(request: Request) { const { searchParams, origin } = new URL(request.url) const code = searchParams.get('code') const requestedNext = searchParams.get('next') const next = requestedNext?.startsWith('/') && !requestedNext.startsWith('//') ? requestedNext : '/'
if (code) { const supabase = await createClient() const { error } = await supabase.auth.exchangeCodeForSession(code) if (!error) return Response.redirect(`${origin}${next}`) }
return Response.redirect(`${origin}/auth/error`)}Next.js에서는 브라우저·서버 클라이언트와 세션 갱신용 Proxy도 필요하다. 전체 파일 구조는 13장을 따른다.
/auth/callback을 거쳐 원하는 페이지로 돌아온다next=//evil.example 값으로 외부 사이트에 이동하지 않는다마지막 두 번째 항목까지 확인해야 Auth 설정이 끝난다. 로그인 성공만 보고 멈추면 인가가 빠진 것이다. 7장에서 RLS 정책을 이어서 설정한다.
처음 한 번은 대시보드가 이해하기 쉽다. 같은 설정을 여러 환경에서 반복하거나 변경 이력을 남기려면
supabase/config.toml과 config push를 쓴다.
[auth]site_url = "https://example.com"additional_redirect_urls = [ "http://localhost:3000/auth/callback", "https://example.com/auth/callback",]
[auth.external.google]enabled = trueclient_id = "<google-client-id>"secret = "env(SUPABASE_AUTH_EXTERNAL_GOOGLE_SECRET)"skip_nonce_check = falsesupabase loginsupabase link --project-ref <project-ref>
# 현재 shell에만 주입하거나 안전한 비밀 저장소에서 읽는다export SUPABASE_AUTH_EXTERNAL_GOOGLE_SECRET='<google-client-secret>'supabase config push로컬 스택만 설정할 때도 같은 config.toml을 읽지만, 변경 후에는
supabase stop && supabase start로 Auth 컨테이너를 다시 띄워야 한다.
로그인된 CLI가 있는 개발 환경을 AI가 사용할 수 있다면 다음 작업은 잘 맡길 수 있다.
config.toml, 로그인 버튼, callback Route Handler, Proxy와 RLS 코드 작성supabase link 뒤 config push, 마이그레이션 적용과 로컬 Auth 테스트vercel link 뒤 환경 변수 등록, Preview/Production 배포와 로그 확인하지만 다음은 사람이 직접 하거나 최종 화면을 확인하는 편이 안전하다.
가장 편한 분업은 다음과 같다.
supabase login, vercel login을 하고 각 CLI를 정확한 프로젝트에 연결한다.AI에게 CLI를 준다는 것은 그 계정의 권한을 함께 준다는 뜻이다. 개인 전체 계정보다 프로젝트 범위가 좁은 권한을 쓰고, 프로덕션 변경 전에는 대상 프로젝트와 환경을 출력해 확인하는 습관이 좋다.
아래는 로그인 하나가 성공한 뒤 필요에 따라 붙인다.
| 기능 | 언제 필요한가 | 읽을 곳 |
|---|---|---|
| 커스텀 SMTP·이메일 템플릿 | 이메일 확인, 매직 링크, 비밀번호 재설정을 프로덕션에서 쓸 때 | Auth 참고서 |
user_metadata와 역할 | 프로필과 관리자·에디터 권한을 구분할 때 | Auth 참고서 |
| MFA | 결제·관리자 기능처럼 재인증이 필요한 작업이 생길 때 | Auth 참고서 |
| Auth Hooks·커스텀 클레임 | 토큰에 역할을 넣거나 자체 메일/SMS를 붙일 때 | Auth 참고서 |
| Admin API | 서버에서 사용자 초대·정지·삭제를 자동화할 때 | Auth 참고서 |
config push — config.toml을 연결된 원격 프로젝트에 반영env add, env update, env pull, env run