Files
Pole-Mapper/LOGIN-PLAN.md
T
2026-09-03 11:50:40 +09:00

5.8 KiB

로그인 기능 추가 구현 계획

1. 사전 준비 (Supabase 대시보드)

  • Authentication → Providers → Email 활성화
  • (선택) 휴대전화 인증 추가 (Twilio 연동 필요)

2. DB 스키마 변경 (supabase-schema.sql)

-- profiles 테이블
create table if not exists profiles (
  id uuid primary key references auth.users(id) on delete cascade,
  role text not null default 'user' check (role in ('admin', 'user')),
  phone text,
  created_at timestamptz not null default now()
);

-- poles RLS
alter table poles enable row level security;

create policy "인증된 사용자 poles 조회"
  on poles for select
  to authenticated
  using (true);

create policy "인증된 사용자 poles 추가"
  on poles for insert
  to authenticated
  with check (true);

create policy "본인 poles 삭제 또는 admin"
  on poles for delete
  to authenticated
  using (
    auth.uid() = (select user_id from profiles where id = poles.id)
    or (select role from profiles where id = auth.uid()) = 'admin'
  );

-- gus/dongs RLS (인증된 사용자 SELECT만 허용)
alter table gus enable row level security;
alter table dongs enable row level security;

create policy "인증된 사용자 gus 조회"
  on gus for select
  to authenticated
  using (true);

create policy "인증된 사용자 dongs 조회"
  on dongs for select
  to authenticated
  using (true);

-- 신규 회원가입 시 profiles 자동 생성 트리거
create or replace function public.handle_new_user()
returns trigger as $$
begin
  insert into public.profiles (id, role)
  values (new.id, 'user');
  return new;
end;
$$ language plpgsql security definer;

create or replace trigger on_auth_user_created
  after insert on auth.users
  for each row execute function public.handle_new_user();

3. 환경 변수 (.env, server/.env, .env.example)

변수 용도
VITE_SUPABASE_URL 프론트엔드 Supabase URL
VITE_SUPABASE_ANON_KEY 프론트엔드 Supabase anon key
SUPABASE_ANON_KEY 서버 JWT 검증용 anon key

anon key는 RLS를 따르므로 클라이언트 노출이 안전합니다.


4. 서버 측 변경

server/auth.js (신규)

  • anon key 기반 Supabase 클라이언트 생성
  • requireAuth 미들웨어 — Authorization: Bearer <token> 토큰 검증 → req.user 주입
  • requireRole(role) 미들웨어 — 역할 확인

server/db.js 변경

  • createProfile(userId, role, phone)
  • getProfile(userId)
  • updateProfileRole(userId, role)
  • getAllProfiles()

server/index.js 변경

신규 API 라우트:

메서드 경로 설명 권한
POST /api/auth/signup 회원가입 (email, password, phone?) 공개
POST /api/auth/login 로그인 → JWT 토큰 반환 공개
GET /api/auth/me 현재 사용자 정보 인증
GET /api/auth/users 사용자 목록 admin
PATCH /api/auth/users/:id/role 역할 변경 admin

기존 라우트 미들웨어 적용:

라우트 권한
GET/POST /api/poles requireAuth
DELETE /api/poles/:id requireAuth + 본인 데이터 또는 admin
GET /api/gus requireAuth
GET /api/dongs requireAuth
GET /api/reverse-geocode requireAuth
GET /api/all-dongs requireAuth

5. 프론트엔드 변경

src/lib/supabase.js (신규)

import { createClient } from '@supabase/supabase-js';
export const supabase = createClient(
  import.meta.env.VITE_SUPABASE_URL,
  import.meta.env.VITE_SUPABASE_ANON_KEY
);

src/App.jsx 변경

인증 상태 관리:

  • user state — Supabase auth 사용자 객체
  • profile state — profiles 테이블에서 가져온 역할 정보
  • useEffect → supabase.auth.onAuthStateChange() 리스닝
  • 컴포넌트 마운트 시 supabase.auth.getSession()으로 기존 세션 복원

조건부 렌더링:

  • user === null → LoginForm / RegisterForm 표시
  • user !== null → 기존 지도 앱 + 상단 UserMenu

LoginForm:

  • 이메일 + 비밀번호 입력
  • supabase.auth.signInWithPassword({ email, password })

RegisterForm:

  • 이메일 + 비밀번호 + (선택) 전화번호 입력
  • supabase.auth.signUp({ email, password, options: { data: { phone } } })

UserMenu (상단):

  • 사용자 이메일/역할 표시
  • 로그아웃 버튼 (supabase.auth.signOut())
  • admin → 사용자관리 링크

UserManagement (admin 전용 패널):

  • 사용자 목록 조회 (GET /api/auth/users)
  • 역할 드롭다운으로 변경 (PATCH /api/auth/users/:id/role)

API 호출 수정 (모든 fetch):

const { data: { session } } = await supabase.auth.getSession();
fetch('/api/poles', {
  headers: { Authorization: `Bearer ${session?.access_token}` }
});

6. 파일 변경 요약

파일 작업
supabase-schema.sql profiles 테이블 + RLS + 트리거 추가
.env / server/.env / .env.example 환경 변수 3개 추가
server/auth.js 신규 — anon 클라이언트 + JWT 미들웨어
server/db.js profiles CRUD 함수 추가
server/index.js auth 라우트 + 기존 라우트에 미들웨어 적용
src/lib/supabase.js 신규 — 클라이언트 Supabase 인스턴스
src/App.jsx 인증 UI + 상태 관리 + API 토큰 헤더 추가

7. 구현 순서

  1. Supabase 대시보드에서 Email auth 활성화
  2. SQL 스키마 업데이트 (profiles + RLS + 트리거)
  3. 환경 변수 추가
  4. server/auth.js 생성
  5. **server/db.js**에 profiles 함수 추가
  6. **server/index.js**에 auth 라우트 + 미들웨어 적용
  7. src/lib/supabase.js 생성
  8. **src/App.jsx**에 인증 UI + 토큰 헤더 추가
  9. 테스트 — 회원가입, 로그인, API 접근, 권한 확인