Files
weeklyreport/claude_temp/04_Gmail_OAuth_로그인_작업계획서.md

25 KiB

Gmail OAuth 로그인 작업계획서

작성일: 2026-01-10 예상 기간: 5~7일 우선순위: 4


1. 기능 개요

1.1 핵심 컨셉

  • Google OAuth + 비밀번호 인증 모두 지원 (개발/운영 동일)
  • Gmail 주소로 기존 사용자(wr_employee_info.email) 매칭
  • 매칭 안되면 로그인 거부 → "관리자에게 문의하세요"
  • OAuth 로그인 후 비밀번호 미설정 시 설정 안내
  • 비밀번호 찾기: 이름+이메일+핸드폰 매칭 → 임시 비밀번호 이메일 발송

1.2 로그인 플로우 (개발/운영 동일)

┌─────────────────────────────────────────────────────────────────┐
│                        로그인 페이지                             │
│                                                                 │
│              [G] Google로 로그인                                │
│              [S] Synology로 로그인  ← (5번 작업 후 추가)        │
│                                                                 │
│              ──────────── 또는 ────────────                     │
│                                                                 │
│              이메일: [_______________]                          │
│              비밀번호: [_______________]                        │
│                                                                 │
│              [로그인]          [비밀번호 찾기]                   │
└─────────────────────────────────────────────────────────────────┘

1.3 Google OAuth 로그인 플로우

[Google로 로그인] 클릭
        ↓
Google OAuth 인증
        ↓
Gmail 주소 획득
        ↓
wr_employee_info.email 매칭?
├─ NO  → "등록되지 않은 사용자입니다. 관리자에게 문의하세요."
└─ YES ↓
        비밀번호 설정됨?
        ├─ YES → 메인 페이지로 이동
        └─ NO  → 비밀번호 설정 페이지
                 "비상시 로그인을 위해 비밀번호를 설정해주세요"

1.4 비밀번호 찾기 플로우

[비밀번호 찾기] 클릭
        ↓
┌─────────────────────────────────────┐
│ 이름:     [_______________]         │
│ 이메일:   [_______________]         │
│ 핸드폰:   [_______________]         │
│                                     │
│           [임시 비밀번호 발송]       │
└─────────────────────────────────────┘
        ↓
세 가지 모두 매칭되는 사용자 확인
├─ 매칭됨   → 이메일로 임시 비밀번호 발송 → "이메일을 확인해주세요"
└─ 불일치   → "일치하는 정보가 없습니다"

1.5 결정 사항

# 항목 결정
1 매칭 안되는 Gmail 로그인 거부, 관리자 문의 안내
2 비밀번호 관리 필수 (OAuth 로그인 후 미설정 시 설정 유도)
3 Google 계정 연결 1인 1계정
4 환경별 로그인 개발/운영 동일 (OAuth + 비밀번호 모두 지원)
5 비밀번호 찾기 이름+이메일+핸드폰 매칭 → 임시 비밀번호 이메일 발송

2. 데이터 모델

2.1 사용자 테이블 수정 (wr_employee_info)

-- 기존 테이블에 컬럼 추가
ALTER TABLE wr_employee_info 
ADD COLUMN password_hash VARCHAR(200),              -- 비밀번호 해시
ADD COLUMN google_id VARCHAR(100),                  -- Google 고유 ID (sub)
ADD COLUMN google_email VARCHAR(100),               -- Google 이메일 (확인용)
ADD COLUMN google_linked_at TIMESTAMP,              -- Google 연결 일시
ADD COLUMN last_login_at TIMESTAMP,                 -- 마지막 로그인
ADD COLUMN last_login_ip VARCHAR(50);               -- 마지막 로그인 IP

-- 인덱스
CREATE UNIQUE INDEX idx_employee_google_id ON wr_employee_info(google_id) WHERE google_id IS NOT NULL;

2.2 로그인 이력 테이블 (wr_login_history) - 선택

CREATE TABLE wr_login_history (
    history_id SERIAL PRIMARY KEY,
    employee_id INTEGER NOT NULL REFERENCES wr_employee_info(employee_id),
    login_type VARCHAR(20) NOT NULL,               -- GOOGLE, PASSWORD
    login_ip VARCHAR(50),
    user_agent VARCHAR(500),
    login_at TIMESTAMP DEFAULT NOW(),
    success BOOLEAN DEFAULT true,
    fail_reason VARCHAR(200)                       -- 실패 시 사유
);

CREATE INDEX idx_login_history_employee ON wr_login_history(employee_id);
CREATE INDEX idx_login_history_at ON wr_login_history(login_at);

3. API 설계

3.1 인증 API

Method Endpoint 설명
GET /api/auth/google Google OAuth 시작 (리다이렉트)
GET /api/auth/google/callback Google 콜백 처리
POST /api/auth/login 이메일/비밀번호 로그인
POST /api/auth/logout 로그아웃
GET /api/auth/me 현재 사용자 정보

3.2 비밀번호 관리 API

Method Endpoint 설명
POST /api/auth/set-password 비밀번호 최초 설정 (OAuth 후)
PUT /api/auth/change-password 비밀번호 변경 (본인)
POST /api/auth/find-password 비밀번호 찾기 (임시 비밀번호 발송)
PUT /api/admin/user/[id]/reset-password 비밀번호 초기화 (관리자)

4. 화면 설계

4.1 로그인 페이지 (/login)

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│                        📊 주간보고 시스템                        │
│                                                                 │
│            ┌─────────────────────────────────────┐              │
│            │         [G] Google로 로그인         │              │
│            └─────────────────────────────────────┘              │
│            ┌─────────────────────────────────────┐              │
│            │       [S] Synology로 로그인         │              │  ← 5번 작업 후
│            └─────────────────────────────────────┘              │
│                                                                 │
│            ─────────────── 또는 ───────────────                 │
│                                                                 │
│            이메일: [_________________________]                  │
│            비밀번호: [_________________________]                │
│                                                                 │
│                   [로그인]    [비밀번호 찾기]                    │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

4.2 비밀번호 설정 페이지 (/auth/set-password)

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│                        🔐 비밀번호 설정                          │
│                                                                 │
│   Google 계정으로 로그인되었습니다.                              │
│   비상시 로그인을 위해 비밀번호를 설정해주세요.                   │
│                                                                 │
│            새 비밀번호:   [_________________________]           │
│            비밀번호 확인: [_________________________]           │
│                                                                 │
│            ※ 8자 이상, 영문+숫자 조합 권장                       │
│                                                                 │
│                        [비밀번호 설정]                           │
│                                                                 │
│                   [나중에 설정하기 →]                            │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

* "나중에 설정하기" 클릭 시 메인으로 이동하지만, 다음 로그인 시 다시 안내

4.3 비밀번호 찾기 페이지 (/auth/find-password)

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│                        🔑 비밀번호 찾기                          │
│                                                                 │
│   등록된 정보와 일치하면 이메일로 임시 비밀번호를 발송합니다.    │
│                                                                 │
│            이름:     [_________________________]                │
│            이메일:   [_________________________]                │
│            핸드폰:   [_________________________]                │
│                                                                 │
│                    [임시 비밀번호 발송]                          │
│                                                                 │
│                       [← 로그인으로]                            │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

           ↓ 발송 성공 시 ↓

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│                        ✅ 발송 완료                              │
│                                                                 │
│   임시 비밀번호가 이메일로 발송되었습니다.                       │
│   이메일: hyo****@company.com                                   │
│                                                                 │
│   ※ 로그인 후 비밀번호를 변경해주세요.                          │
│                                                                 │
│                       [로그인하러 가기]                          │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

4.4 로그인 실패 시 (매칭 안됨)

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│                        ⚠️ 로그인 실패                            │
│                                                                 │
│   "unknown@gmail.com"은 등록되지 않은 사용자입니다.             │
│                                                                 │
│   시스템 사용을 위해서는 관리자에게 문의하여                    │
│   사용자 등록을 요청해주세요.                                   │
│                                                                 │
│   관리자 연락처: admin@company.com                              │
│                                                                 │
│                     [다시 로그인]                               │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

4.4 마이페이지 - 비밀번호 변경 (/mypage)

┌─────────────────────────────────────────────────────────────────┐
│ 마이페이지                                                      │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│ 👤 기본 정보                                                    │
│ ─────────────────────────────────────────────────────────────── │
│ 이름: 조효성                                                    │
│ 이메일: hyosung@company.com                                     │
│ 소속: 개발팀                                                    │
│ 권한: 관리자                                                    │
│                                                                 │
│ 🔗 Google 연결                                                  │
│ ─────────────────────────────────────────────────────────────── │
│ 상태: ✅ 연결됨 (hyosung@gmail.com)                             │
│ 연결일: 2026-01-10                                              │
│                                                                 │
│ 🔒 비밀번호 변경                                                │
│ ─────────────────────────────────────────────────────────────── │
│ 현재 비밀번호: [_________________________]                      │
│ 새 비밀번호:   [_________________________]                      │
│ 비밀번호 확인: [_________________________]                      │
│                                                                 │
│                     [비밀번호 변경]                             │
│                                                                 │
│ 마지막 로그인: 2026-01-10 09:30 (Google)                        │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

4.5 관리자 - 사용자 관리 수정 (/admin/user)

┌─────────────────────────────────────────────────────────────────┐
│ 사용자 상세                                     [수정] [삭제]   │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│ 기본 정보                                                       │
│ ─────────────────────────────────────────────────────────────── │
│ 이름: 조효성                                                    │
│ 이메일: hyosung@company.com                                     │
│ ...                                                             │
│                                                                 │
│ 🔐 계정 관리                                                    │
│ ─────────────────────────────────────────────────────────────── │
│ Google 연결: ✅ 연결됨 (hyosung@gmail.com)     [연결 해제]      │
│ 비밀번호: ********                              [초기화]        │
│ 마지막 로그인: 2026-01-10 09:30                                 │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

* [초기화] 클릭 → 임시 비밀번호 생성 → 사용자에게 전달

5. 환경 설정

5.1 환경 변수

# .env (공통)
# Google OAuth
GOOGLE_CLIENT_ID=xxx.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=xxx
GOOGLE_REDIRECT_URI=https://weeklyreport.company.com/api/auth/google/callback

# 이메일 발송 (비밀번호 찾기용)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=noreply@company.com
SMTP_PASS=xxx
SMTP_FROM=주간보고시스템 <noreply@company.com>

5.2 개발/운영 분기 (필요 시)

# .env.development
GOOGLE_REDIRECT_URI=http://localhost:3000/api/auth/google/callback

# .env.production
GOOGLE_REDIRECT_URI=https://weeklyreport.company.com/api/auth/google/callback

6. Google OAuth 설정

6.1 Google Cloud Console 설정

  1. 프로젝트 생성: Google Cloud Console
  2. OAuth 동의 화면 설정:
    • 앱 이름: 주간보고 시스템
    • 범위: email, profile
  3. 사용자 인증 정보 생성:
    • OAuth 2.0 클라이언트 ID
    • 승인된 리디렉션 URI: https://weeklyreport.company.com/api/auth/google/callback

6.2 OAuth 흐름

1. 사용자 → [Google로 로그인] 클릭
2. 서버 → Google 인증 페이지로 리다이렉트
3. 사용자 → Google 계정 선택, 권한 승인
4. Google → 콜백 URL로 리다이렉트 (code 포함)
5. 서버 → code로 access_token 요청
6. 서버 → access_token으로 사용자 정보 요청
7. 서버 → email로 wr_employee_info 조회
   - 있으면: 세션 생성, 로그인 완료
   - 없으면: 에러 페이지 표시

7. 보안 고려사항

7.1 비밀번호 정책

항목 정책
최소 길이 8자 이상
복잡도 영문 + 숫자 조합 권장
해시 알고리즘 bcrypt (salt rounds: 10)
임시 비밀번호 랜덤 생성 (12자, 영문+숫자+특수문자)

7.2 세션 관리

항목 설정
세션 유효기간 24시간 (또는 설정 가능)
세션 저장소 기존 방식 유지 (쿠키/메모리)
동시 로그인 허용 (기기별 세션)

7.3 비밀번호 찾기 이메일 템플릿

제목: [주간보고시스템] 임시 비밀번호 안내

───────────────────────────────────────

안녕하세요, {이름}님.

요청하신 임시 비밀번호를 안내드립니다.

임시 비밀번호: {임시비밀번호}

보안을 위해 로그인 후 반드시 비밀번호를 변경해주세요.

※ 본 메일은 발신 전용입니다.
※ 본인이 요청하지 않은 경우 관리자에게 문의해주세요.

───────────────────────────────────────
주간보고시스템

8. 작업 일정

Phase 1: DB + 환경 설정 (1일)

  • 시작:
  • 완료:
  • 소요시간:

작업 내용:

  • wr_employee_info 컬럼 추가 (password_hash, google_id 등)
  • wr_login_history 테이블 생성 (선택)
  • 환경 변수 설정 (Google OAuth, SMTP)
  • Google Cloud Console OAuth 설정

Phase 2: 비밀번호 인증 (1.5일)

  • 시작:
  • 완료:
  • 소요시간:

작업 내용:

  • bcrypt 해시 처리
  • 이메일/비밀번호 로그인 API
  • 비밀번호 변경 API
  • 비밀번호 초기화 API (관리자)

Phase 3: Google OAuth (1.5일)

  • 시작:
  • 완료:
  • 소요시간:

작업 내용:

  • Google OAuth 시작/콜백 API
  • 사용자 매칭 로직 (email 기준)
  • 비밀번호 미설정 시 설정 페이지 리다이렉트
  • 비밀번호 최초 설정 API

Phase 4: 비밀번호 찾기 + 이메일 발송 (1일)

  • 시작:
  • 완료:
  • 소요시간:

작업 내용:

  • 이메일 발송 유틸 (nodemailer)
  • 비밀번호 찾기 API (이름+이메일+핸드폰 매칭)
  • 임시 비밀번호 생성 및 발송
  • 비밀번호 찾기 페이지

Phase 5: 로그인 UI + 테스트 (1일)

  • 시작:
  • 완료:
  • 소요시간:

작업 내용:

  • 로그인 페이지 (OAuth + 비밀번호)
  • 비밀번호 설정 페이지
  • 로그인 실패 페이지
  • 마이페이지 비밀번호 변경 UI
  • 관리자 사용자 관리 수정 (비밀번호 초기화)
  • 전체 플로우 테스트

작업 완료 결과

Phase별 작업 시간

Phase 작업 내용 시작 완료 소요시간
1 DB + 환경 설정 - - -
2 비밀번호 인증 - - -
3 Google OAuth - - -
4 비밀번호 찾기 + 이메일 발송 - - -
5 로그인 UI + 테스트 - - -
총 소요시간 -

생성/수정된 파일

구분 파일 작업
DB wr_employee_info 수정 (컬럼 추가)
DB wr_login_history 신규 테이블 (선택)
API backend/api/auth/google.get.ts 신규
API backend/api/auth/google/callback.get.ts 신규
API backend/api/auth/login.post.ts 수정
API backend/api/auth/set-password.post.ts 신규
API backend/api/auth/change-password.put.ts 신규
API backend/api/auth/find-password.post.ts 신규
API backend/api/admin/user/[id]/reset-password.put.ts 신규
Frontend frontend/pages/login.vue 수정
Frontend frontend/pages/auth/set-password.vue 신규
Frontend frontend/pages/auth/find-password.vue 신규
Frontend frontend/pages/mypage.vue 수정
Frontend frontend/pages/admin/user/[id].vue 수정
Utils backend/utils/password.ts 신규
Utils backend/utils/email.ts 신규
Config .env 수정 (OAuth, SMTP 설정)

9. 기술 스택

  • Backend: Nitro (H3) + PostgreSQL
  • Frontend: Nuxt3 + Vue3 + Bootstrap 5
  • OAuth: Google OAuth 2.0
  • 비밀번호: bcrypt
  • 이메일 발송: nodemailer
  • 세션: 기존 방식 유지

10. 향후 확장 고려

  1. Synology SSO 연동: 다음 작업 (5번)
  2. 2단계 인증 (2FA): TOTP 기반 추가 인증
  3. 소셜 로그인 확장: Microsoft, Kakao 등
  4. 비밀번호 만료: 90일 주기 변경 강제
  5. 로그인 알림: 새 기기 로그인 시 이메일 알림
  6. 임시 비밀번호 만료: 24시간 후 만료 처리