docs: NAVER WORKS Passport 구현 완료 상태 반영

- troubleshooting/250917 문서 업데이트
  - Phase 1 로그인: 완료
  - Phase 2 Passport: 완료
  - Frontend 구현: 완료
  - naverworks_token 테이블 정보 업데이트
- ideas/250916 구버전 문서 삭제
This commit is contained in:
happybell80 2025-09-18 00:44:58 +09:00
parent 69349e66c9
commit 6fd35b14b6
2 changed files with 51 additions and 281 deletions

View File

@ -1,250 +0,0 @@
# 네이버웍스 API 연동 가이드
**[현재 프로젝트 상태]** 네이버웍스 API 연동 미구현 (OAuth2 토큰 관리 로직 없음, 관련 skill 서비스 미존재, auth-server에 Works API 인증 미탑재).
## 구현 현황 및 필요 작업
### 현재 상태
- **auth-server**: ✅ Phase 1 로그인 구현 완료 (2025-09-17)
- `/auth/naverworks/login` 작동
- `/auth/naverworks/callback` 작동
- `/auth/naverworks/status` 작동
- **skill 서비스**: NAVER WORKS 전용 스킬 없음 (Phase 2)
- **nginx**: NAVER WORKS 라우팅 설정 없음
- **.env 설정**: ✅ 완료 (NAVER_WORKS_* 변수)
- **Frontend**: ❌ 미구현 (로그인 버튼, Auth Context 수정 필요)
### 확인된 OAuth 엔드포인트 패턴
#### 📍 Google (Gmail) OAuth - 구현됨
**API 엔드포인트**:
- `/auth/gmail/login` - 로그인 시작
- `/auth/gmail/callback` - OAuth 콜백
- `/auth/gmail/passport/` - Passport 로그인 시작
- `/auth/gmail/passport/callback` - Passport 콜백
- `/auth/gmail/passport/status` - Passport 상태 확인
#### 📍 Slack OAuth - 구현됨
**API 엔드포인트**:
- `/auth/slack/login/` - 로그인 시작
- `/auth/slack/login/callback` - OAuth 콜백
- `/auth/slack/passport/install` - Passport 설치
- `/auth/slack/passport/callback` - Passport 콜백
- `/auth/slack/passport/status/{workspace_id}` - Passport 상태
#### 📍 NAVER WORKS OAuth - 구현 예정
**API 엔드포인트** (Gmail/Slack 패턴 참조):
- `/auth/naverworks/login` - 로그인 시작
- `/auth/naverworks/callback` - OAuth 콜백
- `/auth/naverworks/passport/install` - Passport 설치/권한 부여 (선택적)
- `/auth/naverworks/passport/callback` - Passport 콜백 (선택적)
**외부 OAuth URL**:
- **Authorization**: `https://auth.worksmobile.com/oauth2/v2.0/authorize`
- **Token**: `https://auth.worksmobile.com/oauth2/v2.0/token`
- **Userinfo (OIDC)**: `https://www.worksapis.com/v1.0/oidc/userinfo`
- **API Base**: `https://www.worksapis.com/v1.0/`
---
## 1. 로빙(RO-BEING) 앱 설정 현황
- **앱 이름**: Ro-being
- **소속**: company-x.partners (155032)
### 1.1. 인증 정보
- **Client ID**: `[환경변수 NAVERWORKS_CLIENT_ID 참조]`
- **Client Secret**: `[환경변수 NAVERWORKS_CLIENT_SECRET 참조]`
- > **⚠️ 경고: 이 값은 외부에 노출되어서는 안 되며, Git 등 버전 관리 시스템에 포함하지 마십시오. Vault 또는 암호화된 환경 변수를 통해 안전하게 관리해야 합니다.**
- **Service Account**: `[환경변수 NAVERWORKS_SERVICE_ACCOUNT 참조]`
### 1.2. 토큰 설정
- **Access Token 유효기간**: 1시간
- **Refresh Token Rotation**: On (보안 강화)
### 1.3. OAuth 설정
- **구성원 계정 인증 Redirect URL** (콘솔 설정):
- `https://auth.ro-being.com/auth/naverworks/callback` (일반 로그인)
- `https://auth.ro-being.com/auth/naverworks/passport/callback` (Passport 로그인)
- **OIDC Logout Redirection**:
- `https://example.com` (기본값 유지)
- **활성화된 Scopes**:
- `openid`, `profile`, `email` (OIDC 사용자 식별용)
- `calendar` (캘린더 읽기/쓰기)
- `contact` (주소록 읽기/쓰기)
- `file` (드라이브 파일 접근)
- `mail` (메일 읽기/보내기)
- `task` (업무 관리)
- `user` (조직 내 사용자 정보 조회)
---
## 2. 인증 방식
네이버웍스 API를 사용하기 위해서는 먼저 **Access Token**을 발급받아야 합니다. 현재 앱 설정에 따라 아래 두 가지 방식 모두 사용 가능합니다.
1. **구성원 계정으로 인증 (OAuth 2.0 / OIDC)**: 사용자가 직접 로그인하여 자신의 데이터에 대한 접근을 허용하는 방식입니다. (예: "내 캘린더 일정 조회")
2. **서비스 계정으로 인증 (JWT)**: 사용자 로그인 없이, 시스템(로빙)이 조직 전체의 데이터에 접근할 때 사용합니다. (예: 주기적인 데이터 동기화)
## 3. API 사용 예시 및 주요 엔드포인트
### 3.1. 캘린더 (Calendar API)
- **스코프**: `calendar`
- **주요 엔드포인트**:
- `GET /v1.0/users/{userId}/calendar/events`: 특정 사용자의 일정 목록 조회
- `POST /v1.0/users/{userId}/calendar/events`: 새 일정 생성
- `PUT /v1.0/users/{userId}/calendar/events/{eventId}`: 기존 일정 수정
- **요청 예시: 새 일정 생성**
`POST https://www.worksapis.com/v1.0/users/{userId}/calendar/events`
```json
{
"subject": "Team Meeting",
"start": {
"date": "2025-09-18",
"time": "10:00:00"
},
"end": {
"date": "2025-09-18",
"time": "11:00:00"
},
"attendees": [
{
"email": "member1@example.com",
"isOptional": false
}
]
}
```
### 3.2. 주소록 (Contact API)
- **스코프**: `contact`, `user`
- **주요 엔드포인트**:
- `GET /v1.0/contacts`: 고객/거래처 연락처 목록 조회
- `POST /v1.0/contacts`: 새 연락처 생성
- `GET /v1.0/users/{userId}`: 조직 내 사용자 정보 조회
### 3.3. 메일 (Mail API)
- **스코프**: `mail`
- **주요 엔드포인트**:
- `POST /v1.0/users/{userId}/mail`: 메일 발송
- `GET /v1.0/users/{userId}/mail/messages/{messageId}`: 특정 메일 상세 조회
## 4. 로빙 연동 아키텍처
### 4.1. 시크릿 관리 (온프레미스 2서버 환경)
- **원칙**: 영구 시크릿(Client Secret, Private Key)은 **게이트웨이 서버**에만 중앙 집중식으로 보관합니다.
- **구현**: 게이트웨이 서버에서 HashiCorp Vault 또는 암호화된 파일 시스템(`600` 권한)을 사용하여 Client ID/Secret을 관리하고, 컨테이너에는 읽기 전용(`:ro`)으로 마운트합니다.
- **로빙/스킬 서버**: 게이트웨이를 통해 발급된 단기 Access Token만 받아 사용하며, 영구 시크릿을 보관하지 않습니다.
### 4.2. 인증 흐름 및 토큰 관리
- **JWT 키 관리 (JWKS)**: 게이트웨이는 JWT 서명에 사용하는 공개키 목록을 `/.well-known/jwks.json` 엔드포인트를 통해 노출하여, 다른 서비스들이 토큰을 안전하게 검증하고 키 교체에 대응할 수 있도록 합니다.
- **토큰 흐름**: 로빙/스킬 서버는 외부 API를 직접 호출하는 대신, 게이트웨이에 API 호출을 위임하고 필요한 단기 토큰을 받아 사용합니다.
## 5. 구현 필요 사항
### 5.1 파일 생성/수정 목록
#### 생성 필요
- **`auth-server/app/providers/naverworks.py`**: OAuth 2.0 인증 플로우 구현
- **`skill-naverworks/`**: NAVER WORKS API 전용 스킬 서비스 (포트 8511)
#### 수정 필요
- **`auth-server/app/main.py`**: naverworks 라우터 등록 (`prefix="/auth/naverworks"`)
- **`auth-server/.env`**: NAVERWORKS_CLIENT_ID, SECRET, REDIRECT_URI 추가
- **`nginx-infra`**: `/auth/naverworks`, `/api/naverworks` 라우팅 설정
#### DB 스키마
- **Phase 1: 로그인 구현** (현재):
- 기존 `user` 테이블만 사용
- oauth_provider="naverworks"
- oauth_id={userinfo.sub}
- **Phase 2: Passport 구현** (다음):
- `team.naverworks_workspace`: Workspace 정보 저장
- `team.naverworks_token`: access_token/refresh_token 저장
- 메일/캘린더 API 접근용
### 5.2 구현 플로우 (Slack 패턴 참조)
#### OAuth 로그인 엔드포인트
- **GET /auth/naverworks/login/**: State 생성 → Redis 저장 → OAuth 리다이렉트
- **GET /auth/naverworks/callback**: State 검증 → Token 교환 → Userinfo 조회 → User 매핑 → JWT 발급
- 주의: 표준 OAuth 2.0은 GET 콜백 사용 (Slack OIDC의 POST form_post와 다름)
#### Redis Keys
- `oauth:state:{state}`: CSRF 방지용 state 저장 (TTL 300s)
- `auth:temp:{temp_code}`: Frontend 전달용 임시 코드 (TTL 60s)
- `naverworks:service:token`: Service Account 토큰 캐싱 (TTL 3600s)
#### Slack OAuth 참조 파일
- **구현 패턴**: `auth-server/app/providers/slack.py`
- **Gmail passport**: `auth-server/app/providers/gmail_passport.py`
- **JWT 생성**: `auth-server/app/core/auth.py`의 create_access_token()
### 5.3 결정/확인 필요 사항
#### 결정사항 (확정)
- **Redirect URL 도메인**: `auth.ro-being.com` 사용 (Gmail/Slack과 통일)
- **Private Key 처리**:
- 2025-09-17: Git 임시 commit 후 서버 전송
- 서버 저장: Base64 인코딩하여 .env의 NAVERWORKS_PRIVATE_KEY_BASE64에 저장
- Git에서 삭제 완료 (보안상 Git 저장 금지)
- **NAVER WORKS 토큰 테이블**: `naverworks_token` (team 스키마 아래, 단수형)
#### 확인 완료
- **OIDC userinfo 필드**: `sub` (사용자 ID), `email` (이메일)
- **Service Account JWT 서명**: RS256 알고리즘 (RSA 2048 bits)
- **에러 응답 형식**: JSON `{"error", "error_description", "error_uri"}`
- **response_mode**: 기본 query 사용 (form_post 불필요)
## 6. Frontend 수정 계획 (미구현)
### 6.1 로그인 버튼 추가 ❌
- **위치**: `frontend-customer/src/components/login-modal.tsx`
- **아이콘**: `/public/naverworks-icon.svg` (파일은 추가됨)
- **동작**: `/auth/naverworks/login` 리다이렉트
- **상태**: 미구현
### 6.2 Auth Context 수정 ❌
- **위치**: `frontend-customer/src/contexts/auth-context.tsx`
- **함수 추가**: `loginWithNaverWorks()`
- **패턴**: Gmail/Slack과 동일한 OAuth 플로우
- **상태**: 미구현
### 6.3 Skills Panel (Passport 연동) ❌
- **위치**: `frontend-customer/src/components/skills-items-panel.tsx`
- **sessionStorage key**: `naverworks_oauth_return_url`
- **엔드포인트**: `/auth/naverworks/passport/install?user_id={userId}`
- **상태**: Phase 2에서 구현 예정
### 6.4 Callback 처리 ❌
- URL 파라미터에서 임시 코드 추출
- `/auth/verify` 호출로 JWT 획득
- localStorage 토큰 저장
- **상태**: 미구현
### 6.5 UI/UX ❌
- NAVER WORKS 브랜드 색상: 초록색
- 버튼 텍스트: "네이버웍스로 로그인"
- 연동 상태 표시 필요
- **상태**: 미구현
## 7. 참고 자료
- **네이버웍스 개발자 센터 (공식 문서):** [developers.worksmobile.com](https://developers.worksmobile.com)
- [인증 가이드](https://developers.worksmobile.com/kr/docs/auth)
- [캘린더 API](https://developers.worksmobile.com/kr/document/10070?lang=ko)
- [주소록 API](https://developers.worksmobile.com/kr/docs/contact)
- [메일 API](https://developers.worksmobile.com/kr/docs/mail)
- **내부 참조 코드:**
- Slack OAuth: `auth-server/app/providers/slack.py`
- Gmail OAuth: `auth-server/app/providers/gmail_passport.py`

View File

@ -5,11 +5,17 @@
## 구현 현황 (2025-09-17 완료)
### ✅ 구현 완료 사항
- **auth-server**: Phase 1 로그인 구현 완료
- `/auth/naverworks/login` 작동
- `/auth/naverworks/callback` 작동
- ID Token 파싱 방식 구현 (userinfo API 대체)
- 이메일 기반 사용자 통합 (Gmail/Slack과 동일 계정)
- **auth-server**:
- **Phase 1 로그인** (✅ 2025-09-17)
- `/auth/naverworks/login` 작동
- `/auth/naverworks/callback` 작동
- ID Token 파싱 방식 구현 (userinfo API 대체)
- 이메일 기반 사용자 통합 (Gmail/Slack과 동일 계정)
- **Phase 2 Passport** (✅ 2025-09-17)
- `/auth/naverworks/passport/install` 작동
- `/auth/naverworks/passport/callback` 작동
- `/auth/naverworks/passport/status` 작동
- `naverworks_token` 테이블 생성 및 관리
- **Frontend**: OAuth 로그인 구현 완료
- `login-dialog.tsx`에 네이버웍스 버튼 추가
- `auth-context.tsx``loginWithNaverWorks()` 구현
@ -18,7 +24,7 @@
- `NAVER_WORKS_CLIENT_ID`
- `NAVER_WORKS_CLIENT_SECRET`
- `NAVER_WORKS_TENANT_ID`
- **skill 서비스**: Phase 2 예정
- **skill 서비스**: Phase 3 예정
### 확인된 OAuth 엔드포인트 패턴
@ -38,12 +44,15 @@
- `/auth/slack/passport/callback` - Passport 콜백
- `/auth/slack/passport/status/{workspace_id}` - Passport 상태
#### 📍 NAVER WORKS OAuth - 구현 예정
**API 엔드포인트** (Gmail/Slack 패턴 참조):
#### 📍 NAVER WORKS OAuth - 구현 완료
**Phase 1 - 로그인 엔드포인트** (✅ 완료):
- `/auth/naverworks/login` - 로그인 시작
- `/auth/naverworks/callback` - OAuth 콜백
- `/auth/naverworks/passport/install` - Passport 설치/권한 부여 (선택적)
- `/auth/naverworks/passport/callback` - Passport 콜백 (선택적)
**Phase 2 - Passport 엔드포인트** (✅ 완료):
- `/auth/naverworks/passport/install` - Passport 설치/권한 부여
- `/auth/naverworks/passport/callback` - Passport 콜백
- `/auth/naverworks/passport/status` - Passport 상태 확인
**외부 OAuth URL**:
- **Authorization**: `https://auth.worksmobile.com/oauth2/v2.0/authorize`
@ -159,14 +168,19 @@
### 5.1 파일 생성/수정 목록
#### 생성 필요
- **`auth-server/app/providers/naverworks.py`**: OAuth 2.0 인증 플로우 구현
#### 생성 완료
- **`auth-server/app/providers/naverworks.py`**: ✅ OAuth 2.0 인증 플로우 구현
- **`auth-server/app/providers/naverworks_passport.py`**: ✅ Passport 시스템 구현
#### 생성 예정 (Phase 3)
- **`skill-naverworks/`**: NAVER WORKS API 전용 스킬 서비스 (포트 8511)
#### 수정 필요
- **`auth-server/app/main.py`**: naverworks 라우터 등록 (`prefix="/auth/naverworks"`)
- **`auth-server/.env`**: NAVERWORKS_CLIENT_ID, SECRET, REDIRECT_URI 추가
- **`nginx-infra`**: `/auth/naverworks`, `/api/naverworks` 라우팅 설정
#### 수정 완료
- **`auth-server/app/main.py`**: ✅ naverworks 라우터 등록
- `naverworks.router` (`prefix="/auth/naverworks"`)
- `naverworks_passport.router` (`prefix="/auth/naverworks/passport"`)
- **`auth-server/.env`**: ✅ NAVERWORKS_* 환경변수 설정 완료
- **`nginx-infra`**: ✅ `/auth/naverworks` 라우팅 설정
#### DB 스키마
- **Phase 1: 로그인 구현** (현재):
@ -175,9 +189,9 @@
- oauth_id={userinfo.sub}
- 이메일 기반 사용자 통합: Gmail/Slack과 동일 이메일이면 같은 User 레코드 사용
- **Phase 2: Passport 구현** (다음):
- `team.naverworks_workspace`: Workspace 정보 저장
- `team.naverworks_token`: access_token/refresh_token 저장
- **Phase 2: Passport 구현** (✅ 완료):
- `naverworks_token` 테이블: access_token/refresh_token 저장
- 테이블 구조: user_id(PK), domain_id, account_id, token_data, oauth_config, scopes, metadata, expiry, is_equipped, created_at, updated_at
- 메일/캘린더 API 접근용
### 5.2 구현 플로우 (Slack 패턴 참조)
@ -213,43 +227,49 @@
- **에러 응답 형식**: JSON `{"error", "error_description", "error_uri"}`
- **response_mode**: 기본 query 사용 (form_post 불필요)
## 6. Frontend 수정 계획 (미구현)
## 6. Frontend 수정 계획 (✅ 구현 완료)
### 6.1 로그인 버튼 추가
### 6.1 로그인 버튼 추가
- **위치**: `frontend-customer/src/components/login-dialog.tsx` (실제 파일명)
- **아이콘**: `/assets/integrations/naverworks-icon.svg` (파일 존재 확인됨)
- **동작**: `/auth/naverworks/login` 리다이렉트
- **상태**: 구현
- **상태**: 구현 완료
### 6.2 Auth Context 수정
### 6.2 Auth Context 수정
- **위치**: `frontend-customer/src/contexts/auth-context.tsx`
- **함수 추가**: `loginWithNaverWorks()` (context value에 추가 필요)
- **AUTH_SERVER_URL**: `import.meta.env.VITE_AUTH_SERVER_URL || 'https://auth.ro-being.com'` 사용
- **패턴**: Gmail/Slack과 동일한 OAuth 플로우
- **redirect_uri 인코딩**: `encodeURIComponent(window.location.origin)` 필수
- **상태**: 구현
- **상태**: 구현 완료
### 6.3 Skills Panel (Passport 연동)
### 6.3 Skills Panel (Passport 연동)
- **위치**: `frontend-customer/src/components/skills-items-panel.tsx`
- **sessionStorage key**: `naverworks_oauth_return_url`
- **엔드포인트**: `/auth/naverworks/passport/install?user_id={userId}`
- **상태**: Phase 2에서 구현 예정
- **상태**: 구현 완료
### 6.4 Callback 처리
### 6.4 Callback 처리
- URL hash (#auth=임시코드)에서 임시 코드 추출 (기존 코드 패턴)
- `/auth/verify` POST 호출로 JWT 획득
- localStorage 'auth_token' 키로 저장 (주의: 일부 서비스는 'token'도 체크)
- 성공시 URL 정리: `window.history.replaceState()` 사용
- 실패시 에러 처리: `window.location.hash = ''` 및 로그
- **상태**: 구현
- **상태**: 구현 완료
### 6.5 UI/UX
### 6.5 UI/UX
- 버튼 스타일: Google/Slack과 동일한 디자인 사용
- 버튼 텍스트: "NAVER WORKS로 계속하기"
- 연동 상태 표시 필요
- **상태**: 구현
- **상태**: 구현 완료
## 7. 참고 자료
## 7. 수정 이력
- 2025-09-17: Phase 1 로그인 구현 완료
- 2025-09-17: Phase 2 Passport 구현 완료
- 2025-09-18: 테이블명 수정 (naverworks_tokens → naverworks_token)
- 2025-09-18: 문서 업데이트 - Passport 구현 완료 상태 반영
## 8. 참고 자료
- **네이버웍스 개발자 센터 (공식 문서):** [developers.worksmobile.com](https://developers.worksmobile.com)
- [인증 가이드](https://developers.worksmobile.com/kr/docs/auth)