OPEN HYPER STEP
← 목록으로 (ai-startup)
AI-STARTUP · 27 / 100
ai-startup
CHAPTER 27 / 100
읽기 약 2
FUNCTION

사용자 인증: Supabase Auth + 소셜 로그인


핵심 개념

Email/Password·Google·GitHub OAuth·Magic Link·RLS 통합.

본문

Supabase Auth 활성화

📋 코드 (7줄)
1. Supabase Console → Authentication → Providers
2. Email 활성 (기본)
3. Google OAuth 추가:
   - Google Cloud Console에서 Client ID/Secret
   - Supabase에 입력
4. GitHub 추가 (동일)
5. Magic Link (이메일만으로 로그인) 활성

클라이언트 셋업

TYPESCRIPT📋 코드 (31줄)
// lib/supabase/client.ts
import { createBrowserClient } from '@supabase/ssr';

export function createClient() {
  return createBrowserClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
  );
}


// lib/supabase/server.ts (Server Components)
import { createServerClient } from '@supabase/ssr';
import { cookies } from 'next/headers';

export async function createClient() {
  const cookieStore = await cookies();
  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll: () => cookieStore.getAll(),
        setAll: (cookiesToSet) => {
          cookiesToSet.forEach(({ name, value, options }) =>
            cookieStore.set(name, value, options));
        },
      },
    },
  );
}

로그인 페이지

TSX📋 코드 (34줄)
'use client';
import { createClient } from '@/lib/supabase/client';

export default function LoginPage() {
  const supabase = createClient();

  const signInWithGoogle = async () => {
    await supabase.auth.signInWithOAuth({
      provider: 'google',
      options: {
        redirectTo: `${location.origin}/auth/callback`,
      },
    });
  };

  const signInWithMagicLink = async (email: string) => {
    const { error } = await supabase.auth.signInWithOtp({
      email,
      options: {
        emailRedirectTo: `${location.origin}/auth/callback`,
      },
    });
    if (error) toast.error(error.message);
    else toast.success('이메일 확인해주세요');
  };

  return (
    <div className="space-y-4">
      <button onClick={signInWithGoogle}>Google로 시작</button>
      <button onClick={signInWithGitHub}>GitHub로 시작</button>
      <MagicLinkForm onSubmit={signInWithMagicLink} />
    </div>
  );
}

OAuth Callback

TYPESCRIPT📋 코드 (17줄)
// app/auth/callback/route.ts
import { NextResponse } from 'next/server';
import { createClient } from '@/lib/supabase/server';

export async function GET(request: Request) {
  const { searchParams, origin } = new URL(request.url);
  const code = searchParams.get('code');
  const next = searchParams.get('next') ?? '/dashboard';

  if (code) {
    const supabase = await createClient();
    const { error } = await supabase.auth.exchangeCodeForSession(code);
    if (!error) return NextResponse.redirect(`${origin}${next}`);
  }

  return NextResponse.redirect(`${origin}/auth/error`);
}

미들웨어 — 인증 보호

TYPESCRIPT📋 코드 (34줄)
// middleware.ts
import { createServerClient } from '@supabase/ssr';
import { NextResponse, NextRequest } from 'next/server';

export async function middleware(req: NextRequest) {
  let res = NextResponse.next({ request: req });

  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll: () => req.cookies.getAll(),
        setAll: (cookiesToSet) => {
          cookiesToSet.forEach(({ name, value, options }) =>
            res.cookies.set(name, value, options));
        },
      },
    },
  );

  const { data: { user } } = await supabase.auth.getUser();

  // 보호 경로
  if (!user && req.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', req.url));
  }

  return res;
}

export const config = {
  matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
};

RLS (Row Level Security) — 자동 격리

SQL📋 코드 (11줄)
-- 모든 테이블에 RLS
ALTER TABLE chats ENABLE ROW LEVEL SECURITY;

-- 사용자는 자기 chat만
CREATE POLICY "users_own_chats"
  ON chats FOR ALL
  USING (user_id = auth.uid());


-- 자동: SELECT, INSERT, UPDATE, DELETE 모두 검증
-- → 백엔드에서 user_id 필터 안 해도 안전

다음 챕터

CH.28 "AI 기능 구현: OpenAI/Claude API 연동".


AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
무료

월 $0 — 검증·시작 단계

Supabase Auth을 무료 도구만으로
시작하는 방법을 알려줘.
소자본

월 $20~50 — MVP·초기 운영

월 $20~50 예산으로 Supabase Auth을
검증·MVP 단계까지 진행하는 전략은?
프로덕션

월 $200~500 — 성장 단계

Supabase Auth을 프로덕션 단계로
확장할 때 필요한 도구·운영 체계는?
스택

풀스택 — 도구 조합 분석

2026년 Supabase Auth 관련 도구 5개를
조합한 추천 스택을 알려줘.

⭐ 이것만 기억하세요
사용자 인증: Supabase Auth + 소셜 로그인 이 3가지만 확실히 잡으세요
1.Supabase Auth = OAuth + Magic Link + RLS 통합 — 30분 셋업
2.미들웨어로 자동 인증 검증 — 보호 경로 명시
3.RLS로 DB 레벨 격리 — 백엔드 user_id 필터 불필요


공유하기
진행도 27 / 100