Files
weeklyreport/claude_temp/05_Synology_SSO_연동_작업계획서.md

22 KiB

Synology SSO 연동 작업계획서

작성일: 2026-01-10 예상 기간: 2~3일 우선순위: 5 선행 작업: 4번 (Gmail OAuth 로그인)


1. 기능 개요

1.1 핵심 컨셉

  • 사내 Synology NAS의 SSO Server를 통한 로그인
  • 4번(Gmail OAuth)과 동일한 구조로 구현
  • Google OAuth와 병행 사용 가능 (사용자 선택)
  • Synology 계정 이메일로 기존 사용자 매칭

1.2 로그인 페이지

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

1.3 Synology SSO 로그인 플로우

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

1.4 결정 사항

# 항목 결정
1 매칭 기준 Synology 계정 이메일 ↔ wr_employee_info.email
2 매칭 안됨 로그인 거부, 관리자 문의 안내
3 비밀번호 미설정 4번과 동일하게 설정 유도
4 Google/Synology 동시 연결 허용 (1인 1계정씩)

2. Synology SSO Server 개요

2.1 SSO Server란?

  • Synology NAS에서 제공하는 OAuth 2.0 기반 인증 서버
  • DSM (DiskStation Manager) 패키지로 설치
  • 사내 NAS 계정으로 외부 애플리케이션 로그인 가능

2.2 OAuth 2.0 흐름 (Google과 동일)

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

3. 데이터 모델

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

-- 4번 작업에서 추가한 컬럼에 Synology 관련 컬럼 추가
ALTER TABLE wr_employee_info 
ADD COLUMN synology_id VARCHAR(100),              -- Synology 고유 ID
ADD COLUMN synology_username VARCHAR(100),        -- Synology 사용자명
ADD COLUMN synology_linked_at TIMESTAMP;          -- Synology 연결 일시

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

3.2 최종 사용자 테이블 구조 (4번 + 5번)

-- wr_employee_info 인증 관련 컬럼 요약
employee_id         SERIAL PRIMARY KEY,
...
-- 비밀번호 (4번)
password_hash       VARCHAR(200),

-- Google OAuth (4번)
google_id           VARCHAR(100),
google_email        VARCHAR(100),
google_linked_at    TIMESTAMP,

-- Synology SSO (5번)
synology_id         VARCHAR(100),
synology_username   VARCHAR(100),
synology_linked_at  TIMESTAMP,

-- 공통
last_login_at       TIMESTAMP,
last_login_ip       VARCHAR(50),
last_login_type     VARCHAR(20),    -- PASSWORD, GOOGLE, SYNOLOGY
...

4. API 설계

4.1 Synology SSO API

Method Endpoint 설명
GET /api/auth/synology Synology OAuth 시작 (리다이렉트)
GET /api/auth/synology/callback Synology 콜백 처리

4.2 기존 API와 통합

Method Endpoint 설명 비고
GET /api/auth/me 현재 사용자 정보 login_type 포함
POST /api/auth/logout 로그아웃 공통

5. Synology SSO Server 설정 가이드

5.1 SSO Server 패키지 설치

  1. DSM 접속: https://nas.company.com:5001 관리자 계정으로 로그인
  2. 패키지 센터 열기
  3. "SSO Server" 검색 → 설치
  4. 설치 완료 후 열기
패키지 센터 > 검색: "SSO Server" > [설치]

5.2 SSO Server 기본 설정

  1. SSO Server 앱 열기
  2. 설정 탭 진입
  3. 기본 설정 확인:
설정 항목 권장 값
SSO 서비스 활성화 체크
HTTPS 사용 체크 (필수)
포트 5001 (기본값)

5.3 애플리케이션 등록

  1. SSO Server > 애플리케이션
  2. [추가] 버튼 클릭
  3. 아래 정보 입력:
┌─────────────────────────────────────────────────────────────────┐
│ 애플리케이션 추가                                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│ 애플리케이션 이름: [주간보고시스템________________]             │
│                                                                 │
│ 리디렉션 URI:                                                   │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ https://weeklyreport.company.com/api/auth/synology/callback │ │
│ └─────────────────────────────────────────────────────────────┘ │
│                                                                 │
│ ※ 개발용 추가 (선택):                                          │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ http://localhost:3000/api/auth/synology/callback            │ │
│ └─────────────────────────────────────────────────────────────┘ │
│                                                                 │
│                              [저장]                             │
└─────────────────────────────────────────────────────────────────┘
  1. 저장Client ID / Client Secret 확인 및 복사
┌─────────────────────────────────────────────────────────────────┐
│ 애플리케이션 정보                                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│ 애플리케이션 이름: 주간보고시스템                               │
│                                                                 │
│ Client ID:     abc123def456...                    [복사]        │
│ Client Secret: xyz789ghi012...                    [복사]        │
│                                                                 │
│ ※ Client Secret은 다시 볼 수 없으니 반드시 복사해두세요!       │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

5.4 사용자 권한 설정

  1. SSO Server > 권한
  2. 로그인 허용할 사용자/그룹 선택
┌─────────────────────────────────────────────────────────────────┐
│ 권한 설정                                                       │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│ 애플리케이션: 주간보고시스템                                    │
│                                                                 │
│ 허용된 사용자/그룹:                                             │
│ ☑ administrators                                                │
│ ☑ developers                                                    │
│ ☑ users                                                         │
│ ☐ guests                                                        │
│                                                                 │
│ ※ 또는 [모든 사용자 허용] 선택                                  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

5.5 HTTPS/SSL 인증서 확인

제어판 > 보안 > 인증서에서 유효한 SSL 인증서 확인

확인 항목 필수 여부
유효한 SSL 인증서 필수
인증서 만료일 확인 확인
Let's Encrypt 또는 정식 인증서 권장
※ 자체 서명 인증서(Self-signed)는 브라우저 경고 발생할 수 있음
※ Let's Encrypt 무료 인증서 권장

5.6 방화벽/포트 설정

외부에서 NAS 접근이 필요한 경우:

포트 용도 필요 여부
5001 DSM HTTPS 필수
443 역방향 프록시 사용 시 선택
※ 공유기/방화벽에서 5001 포트 개방 필요
※ 또는 역방향 프록시로 443 → 5001 연결

5.7 설정 완료 체크리스트

# 항목 확인
1 SSO Server 패키지 설치
2 SSO 서비스 활성화
3 애플리케이션 등록 (주간보고시스템)
4 Client ID 복사
5 Client Secret 복사
6 리디렉션 URI 설정 (운영)
7 리디렉션 URI 설정 (개발) - 선택
8 사용자/그룹 권한 설정
9 SSL 인증서 유효 확인
10 외부 접근 테스트

5.8 설정 후 .env 파일 업데이트

# Synology SSO (5.3에서 복사한 값 입력)
SYNOLOGY_SSO_URL=https://nas.company.com:5001
SYNOLOGY_CLIENT_ID=여기에_Client_ID_붙여넣기
SYNOLOGY_CLIENT_SECRET=여기에_Client_Secret_붙여넣기
SYNOLOGY_REDIRECT_URI=https://weeklyreport.company.com/api/auth/synology/callback

6. 구현 상세

6.1 Synology OAuth 엔드포인트

# 인증 요청 (Authorization)
GET https://{SYNOLOGY_SSO_URL}/webman/sso/SSOOauth.cgi
    ?response_type=code
    &client_id={CLIENT_ID}
    &redirect_uri={REDIRECT_URI}
    &scope=user_id

# 토큰 요청 (Token)
POST https://{SYNOLOGY_SSO_URL}/webman/sso/SSOAccessToken.cgi
    Content-Type: application/x-www-form-urlencoded
    
    grant_type=authorization_code
    &code={CODE}
    &client_id={CLIENT_ID}
    &client_secret={CLIENT_SECRET}
    &redirect_uri={REDIRECT_URI}

# 사용자 정보 요청 (UserInfo)
GET https://{SYNOLOGY_SSO_URL}/webman/sso/SSOUserInfo.cgi
    ?access_token={ACCESS_TOKEN}

6.2 사용자 정보 응답 예시

{
  "data": {
    "email": "hyosung@company.com",
    "user_id": 1001,
    "user_name": "hyosung"
  },
  "success": true
}

6.3 API 구현 코드 (예시)

// backend/api/auth/synology.get.ts
export default defineEventHandler((event) => {
  const config = useRuntimeConfig();
  
  const authUrl = new URL(`${config.synologySsoUrl}/webman/sso/SSOOauth.cgi`);
  authUrl.searchParams.set('response_type', 'code');
  authUrl.searchParams.set('client_id', config.synologyClientId);
  authUrl.searchParams.set('redirect_uri', config.synologyRedirectUri);
  authUrl.searchParams.set('scope', 'user_id');
  
  return sendRedirect(event, authUrl.toString());
});

// backend/api/auth/synology/callback.get.ts
export default defineEventHandler(async (event) => {
  const query = getQuery(event);
  const code = query.code as string;
  
  if (!code) {
    return sendRedirect(event, '/login?error=no_code');
  }
  
  // 1. Access Token 요청
  const tokenResponse = await $fetch(`${config.synologySsoUrl}/webman/sso/SSOAccessToken.cgi`, {
    method: 'POST',
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      code,
      client_id: config.synologyClientId,
      client_secret: config.synologyClientSecret,
      redirect_uri: config.synologyRedirectUri,
    }),
  });
  
  // 2. 사용자 정보 요청
  const userInfo = await $fetch(`${config.synologySsoUrl}/webman/sso/SSOUserInfo.cgi`, {
    params: { access_token: tokenResponse.access_token },
  });
  
  // 3. 이메일로 사용자 매칭
  const employee = await findEmployeeByEmail(userInfo.data.email);
  
  if (!employee) {
    return sendRedirect(event, '/login?error=not_registered');
  }
  
  // 4. Synology 정보 업데이트
  await updateEmployeeSynologyInfo(employee.employee_id, {
    synology_id: userInfo.data.user_id,
    synology_username: userInfo.data.user_name,
  });
  
  // 5. 세션 생성
  await createSession(event, employee, 'SYNOLOGY');
  
  // 6. 비밀번호 설정 여부 확인
  if (!employee.password_hash) {
    return sendRedirect(event, '/auth/set-password');
  }
  
  return sendRedirect(event, '/');
});

7. 화면 설계

7.1 로그인 페이지 수정 (/login)

4번 작업에서 만든 로그인 페이지에 Synology 버튼 추가

<template>
  <div class="login-buttons">
    <!-- Google 로그인 -->
    <a href="/api/auth/google" class="btn btn-outline-danger btn-lg w-100 mb-2">
      <i class="bi bi-google me-2"></i> Google로 로그인
    </a>
    
    <!-- Synology 로그인 -->
    <a href="/api/auth/synology" class="btn btn-outline-primary btn-lg w-100 mb-3">
      <i class="bi bi-hdd-network me-2"></i> Synology로 로그인
    </a>
    
    <hr class="my-3">
    
    <!-- 이메일/비밀번호 로그인 -->
    ...
  </div>
</template>

7.2 마이페이지 수정 (/mypage)

┌─────────────────────────────────────────────────────────────────┐
│ 마이페이지                                                      │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│ 👤 기본 정보                                                    │
│ ─────────────────────────────────────────────────────────────── │
│ 이름: 조효성                                                    │
│ 이메일: hyosung@company.com                                     │
│ ...                                                             │
│                                                                 │
│ 🔗 외부 계정 연결                                               │
│ ─────────────────────────────────────────────────────────────── │
│                                                                 │
│ Google:   ✅ 연결됨 (hyosung@gmail.com)        [연결 해제]      │
│           연결일: 2026-01-10                                    │
│                                                                 │
│ Synology: ✅ 연결됨 (hyosung)                  [연결 해제]      │
│           연결일: 2026-01-10                                    │
│                                                                 │
│ 🔒 비밀번호                                                     │
│ ─────────────────────────────────────────────────────────────── │
│ ...                                                             │
│                                                                 │
│ 마지막 로그인: 2026-01-10 09:30 (Synology)                      │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

8. 작업 일정

Phase 1: Synology SSO 설정 + API (1.5일)

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

작업 내용:

  • Synology SSO Server 애플리케이션 등록
  • wr_employee_info 컬럼 추가 (synology_id 등)
  • 환경 변수 설정
  • Synology OAuth 시작/콜백 API
  • 사용자 매칭 로직

Phase 2: UI + 테스트 (1일)

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

작업 내용:

  • 로그인 페이지에 Synology 버튼 추가
  • 마이페이지 외부 계정 연결 표시
  • 로그인 이력에 login_type 기록
  • 전체 플로우 테스트

작업 완료 결과

Phase별 작업 시간

Phase 작업 내용 시작 완료 소요시간
1 Synology SSO 설정 + API - - -
2 UI + 테스트 - - -
총 소요시간 -

생성/수정된 파일

구분 파일 작업
DB wr_employee_info 수정 (synology 컬럼 추가)
API backend/api/auth/synology.get.ts 신규
API backend/api/auth/synology/callback.get.ts 신규
Frontend frontend/pages/login.vue 수정
Frontend frontend/pages/mypage.vue 수정
Config .env 수정 (Synology 설정 추가)

9. 기술 스택

  • Backend: Nitro (H3) + PostgreSQL
  • Frontend: Nuxt3 + Vue3 + Bootstrap 5
  • OAuth: Synology SSO Server (OAuth 2.0)
  • 세션: 기존 방식 유지 (4번과 공유)

10. 주의사항

10.1 Synology SSO Server 요구사항

  • DSM 7.0 이상 권장
  • SSO Server 패키지 설치 필요
  • HTTPS 필수 (유효한 SSL 인증서)

10.2 네트워크 설정

  • 외부에서 Synology NAS 접근 가능해야 함
  • 방화벽에서 5001 포트 (HTTPS) 허용 필요
  • 또는 역방향 프록시 설정

10.3 개발 환경 제약

  • localhost 콜백이 안 될 수 있음
  • ngrok 또는 개발용 도메인 필요할 수 있음

11. 향후 확장 고려

  1. LDAP 연동: Synology LDAP Server와 통합
  2. 그룹 기반 권한: Synology 그룹 → 시스템 권한 매핑
  3. 자동 사용자 생성: Synology 계정 → 자동 사용자 등록 (관리자 승인)