Files
zellyy-finance/docs/clerk-supabase-setup.md
hansoo c231d5be65 feat: Clerk + Supabase 통합 시스템 구현 완료
주요 변경사항:
• Clerk 인증 시스템 통합 및 설정
• Supabase 데이터베이스 스키마 설계 및 적용
• JWT 기반 Row Level Security (RLS) 정책 구현
• 기존 Appwrite 인증을 Clerk로 완전 교체

기술적 개선:
• 무한 로딩 문제 해결 - Index.tsx 인증 로직 수정
• React root 마운팅 오류 수정 - main.tsx 개선
• CORS 설정 추가 - vite.config.ts 수정
• Sentry 에러 모니터링 통합

추가된 컴포넌트:
• AuthGuard: 인증 보호 컴포넌트
• SignIn/SignUp: Clerk 기반 인증 UI
• ClerkProvider: Clerk 설정 래퍼
• EnvTest: 개발환경 디버깅 도구

데이터베이스:
• user_profiles, transactions, budgets, category_budgets 테이블
• Clerk JWT 토큰 기반 RLS 정책
• 자동 사용자 프로필 생성 및 동기화

Task Master:
• Task 11.1, 11.2, 11.4 완료
• 프로젝트 관리 시스템 업데이트

Note: ESLint 정리는 별도 커밋에서 진행 예정

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-13 14:01:27 +09:00

3.1 KiB

Clerk + Supabase 통합 설정 가이드

1. Clerk 대시보드 설정

JWT Template 생성

  1. Clerk 대시보드에 로그인
  2. 프로젝트 선택 (joint-cheetah-86)
  3. JWT Templates 섹션으로 이동
  4. Create Template 클릭
  5. 다음 설정 적용:
{
  "name": "supabase",
  "claims": {
    "aud": "authenticated",
    "role": "authenticated",
    "email": "{{user.primary_email_address}}",
    "email_verified": true,
    "phone": "{{user.primary_phone_number}}",
    "app_metadata": {
      "provider": "clerk",
      "providers": ["clerk"]
    },
    "user_metadata": {
      "name": "{{user.full_name}}",
      "username": "{{user.username}}",
      "avatar_url": "{{user.image_url}}"
    }
  },
  "lifetime": 3600
}

소셜 로그인 설정 (Task 11.3 예정)

  1. Social Connections 섹션
  2. 다음 제공자 활성화:
    • Google
    • GitHub
    • 카카오 (Custom OAuth)
    • 네이버 (Custom OAuth)

2. Supabase 설정

JWT Secret 설정

  1. Supabase 대시보드에서 SettingsAPI
  2. JWT Secret 섹션에서 Clerk의 JWT 공개 키 설정
  3. Clerk 대시보드에서 API KeysJWT Public Key 복사

RLS 정책 수정

-- Clerk JWT를 위한 함수 생성
CREATE OR REPLACE FUNCTION auth.clerk_user_id() 
RETURNS TEXT AS $$
  SELECT COALESCE(
    current_setting('request.jwt.claims', true)::json->>'sub',
    (current_setting('request.jwt.claims', true)::json->'raw_user_meta_data'->>'sub')
  )::text;
$$ LANGUAGE SQL STABLE;

-- RLS 정책 업데이트 (이미 생성된 정책 수정)
ALTER POLICY "사용자는 자신의 프로필만 조회 가능" ON user_profiles
  USING (clerk_user_id = auth.clerk_user_id());

3. 환경 변수 설정

.env:

# Clerk
VITE_CLERK_PUBLISHABLE_KEY=pk_test_am9pbnQtY2hlZXRhaC04Ni5jbGVyay5hY2NvdW50cy5kZXYk

# Supabase
VITE_SUPABASE_URL=https://qnerebtvwwfobfzdoftx.supabase.co
VITE_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

4. 코드 통합 체크리스트

완료된 작업

  • Supabase 클라이언트 설정 (src/lib/supabase/client.ts)
  • Clerk 인증 훅 생성 (src/lib/supabase/auth.ts)
  • AuthGuard 컴포넌트 생성
  • SignIn/SignUp 컴포넌트 생성
  • 라우팅 설정

다음 단계

  • Clerk 대시보드에서 JWT 템플릿 생성
  • Supabase에서 Clerk JWT 공개 키 설정
  • RLS 정책 업데이트
  • 기존 Appwrite 코드 제거 (Task 11.4)
  • 데이터 마이그레이션 (Task 11.5)

5. 테스트

  1. 애플리케이션 실행
  2. /sign-up에서 새 계정 생성
  3. Supabase 대시보드에서 user_profiles 테이블 확인
  4. 프로필이 자동 생성되었는지 확인

6. 트러블슈팅

JWT 토큰 오류

  • Clerk 대시보드에서 JWT 템플릿 이름이 'supabase'인지 확인
  • Supabase에 Clerk JWT 공개 키가 올바르게 설정되었는지 확인

RLS 오류

  • auth.clerk_user_id() 함수가 생성되었는지 확인
  • RLS 정책이 업데이트되었는지 확인

프로필 생성 실패

  • Clerk 사용자 ID가 올바르게 전달되는지 확인
  • Supabase 연결이 정상인지 확인