Files
MyDoc/바론SSO 사용자 프로필 사진연동 관련 검토.md

337 lines
14 KiB
Markdown

# tdc114plus 프로필 사진 식별자 매핑 및 소스 우선순위 검토안
작성일: 2026-07-14
상태: draft
관련 Phase: `Phase 7-C`
## 1. 목적
신규앱에서 직원 프로필 사진을 노출할 때, 어떤 이미지 소스를 어떤 우선순위로 사용할지 정하고, 기존 이미지 파일명 규칙을 앱이 직접 사용하지 않도록 외부서버와 신규앱의 역할을 정리한다.
본 문서는 아래를 결정하기 위한 검토 초안이다.
- 기존 `이메일 @ 앞부분.jpg` 자산을 어떻게 안전하게 재사용할지
- 네이버웍스 사진, 외부서버 매핑 사진, 앱 기본 아바타의 우선순위를 어떻게 정할지
- 외부서버에서 어떤 테이블과 조회 인터페이스를 제공해야 하는지
- 신규앱에서 어떤 식별값으로 프로필 이미지를 표현해야 하는지
- DTO 또는 계약에 어떤 보강이 필요한지
## 2. 현재 상황
- 신규앱은 프로필 사진 파일을 자체 저장하거나 자체 파일명 규칙으로 관리하지 않는다.
- Baron SSO는 현재 네이버웍스와 강하게 연결되어 있으며, 네이버웍스 사진을 우선 활용하는 방향으로 정리되어 있다.
- 네이버웍스 프로필 사진 연동 검토를 위해 사용할 개발자계정이 별도로 공유될 예정이다.
- 현재 프로필 이미지는 특정 외부서버에 있는 파일 링크 또는 이미지 URL을 통해 표현하는 방향이다.
- 기존 이미지 파일명은 `직원 이메일 @ 앞부분.jpg` 규칙을 따른다.
- `이메일 @ 앞부분`은 사내 개인 고유키 성격을 가지므로, 신규앱이 이 값을 직접 파일명으로 사용하거나 URL 규칙으로 유추하는 방식은 피해야 한다.
현재 정리된 1차 방향은 아래와 같다.
1. 네이버웍스에 해당 직원 사진이 있으면 그 사진을 먼저 표현한다.
2. 네이버웍스 사진이 없으면, 외부서버의 `photoLookupKey` 기반 매핑 구조로 사진을 조회한다.
3. 그마저도 사진이 없거나 조회에 실패하면, 신규앱이 현재 제공하는 기본 프로필 이미지를 사용한다.
## 3. 기본 판단
- 앱의 최우선 사진 소스는 네이버웍스여야 한다.
- 앱이 `이메일 @ 앞부분.jpg`를 직접 조합하는 방식은 보안 권고와 충돌하므로 장기 유지안으로 보기 어렵다.
- 외부서버는 이미지 원본 파일명과 분리된 별도 조회 키를 제공해야 한다.
- 신규앱은 네이버웍스 사진이 없는 경우에만 `photoLookupKey` 같은 대체 식별자로 외부서버 이미지를 조회해야 한다.
- 가능하면 앱이 원본 식별값으로 해시를 직접 계산하기보다, 서버 또는 DTO가 `photoLookupKey`를 직접 제공하는 구조가 더 안전하고 단순하다.
## 4. 목표
- 네이버웍스 사진을 1순위 소스로 사용한다.
- 내부 파일명 규칙을 앱과 외부 URL에 직접 노출하지 않는다.
- 기존 이미지 자산을 전면 재가공하지 않고 재사용 가능하게 만든다.
- 직원검색, 조직도, 직원 상세 화면에서 동일한 규칙으로 프로필 사진을 노출한다.
- 이미지가 없거나 매핑이 실패해도 기본 아바타 fallback을 유지한다.
## 5. 권장 구조
### 5-1. 핵심 구조
1. 신규앱은 먼저 네이버웍스 사진을 조회하거나 네이버웍스 사진 URL/식별값을 우선 사용한다.
2. 네이버웍스 사진이 없을 때만 외부서버 기반 fallback 경로로 내려간다.
3. 외부서버는 기존 이미지 파일과 사용자 정보를 기준으로 매핑 테이블을 만든다.
4. 외부서버는 원본 파일명 대신 `photoLookupKey`를 생성해 저장한다.
5. 신규앱은 직원 DTO 또는 별도 응답에서 `photoLookupKey`를 받는다.
6. 신규앱은 `photoLookupKey`를 이용해 외부서버의 이미지 조회 endpoint만 호출한다.
7. 외부서버는 내부적으로 실제 파일을 찾아 이미지를 응답한다.
8. 네이버웍스 사진도 없고 외부서버 사진도 없으면 앱 기본 아바타를 표시한다.
### 5-2. 프로필 사진 소스 우선순위
신규앱의 프로필 사진 노출 우선순위는 아래와 같이 본다.
1. 네이버웍스 사진
2. 외부서버 `photoLookupKey` 기반 이미지
3. 신규앱 기본 아바타
즉, 이번 문서에서 정리한 외부서버 매핑 구조는 기본 경로가 아니라 `2차 fallback 경로`다.
### 5-3. 쉽게 설명한 구조
쉽게 말하면 앱은 사진을 아래 순서로 찾는다.
- 먼저 네이버웍스에서 사진이 있는지 본다
- 없으면 외부서버에 `photoLookupKey`로 사진이 있는지 본다
- 그것도 없으면 앱 기본 이미지를 보여준다
그리고 외부서버 fallback을 사용할 때도, 기존 방식처럼 앱이 직접 파일명을 만들어 찾지는 않는다.
기존 방식은 앱이 직접 파일명을 만들어 창고 물건 이름을 바로 찾아가는 방식에 가깝다.
- 앱이 이메일을 안다
- 앱이 `@` 앞부분을 뽑는다
- 앱이 `kimss.jpg` 같은 파일명을 만든다
- 앱이 그 파일명을 URL에 붙여 직접 호출한다
권장 방식은 앱이 파일명을 모르고, 보관증 번호만 내는 방식이다.
- 앱은 `photoLookupKey`만 안다
- 앱은 `GET /profile-images/{photoLookupKey}` 같은 주소만 호출한다
- 외부서버가 내부 테이블을 조회한다
- 외부서버가 실제 파일을 찾아 이미지로 응답한다
이렇게 하면 앱이 내부 파일명 규칙을 알 필요가 없다.
## 6. 외부서버(테이블) 측 단계별 작업
### 6-1. 원본 기준값 확정
기존 이미지 파일명이 `이메일 @ 앞부분.jpg` 규칙을 사용하므로, 외부서버 내부 기준값은 우선 `email local-part`를 원본 식별값으로 사용한다.
### 6-2. 대체 식별자 생성 규칙 확정
원본 식별값을 외부에 직접 노출하지 않도록 `photoLookupKey`를 생성한다.
권고 방향:
- 단순 평문 재사용 금지
- 단순 파일명 재사용 금지
- 서버 비밀값 기반의 `HMAC(email local-part)` 또는 이에 준하는 결정적 식별자 우선 검토
### 6-3. 매핑 테이블 설계
최소 컬럼 초안:
- `photo_lookup_key`
- `image_path` 또는 `image_url`
- `employee_name`
- `phone_number`
- `email`
- `status`
- `updated_at`
운영상 필요하면 원본 `email local-part`를 내부 관리용으로 둘 수 있으나, 접근 권한은 제한하고 앱이나 공개 URL에는 직접 노출하지 않는다.
### 6-4. 기존 이미지와 사용자 정보 적재
기존 `이메일 @ 앞부분.jpg` 파일 목록과 Baron SSO 사용자 정보를 대조해 초기 매핑 데이터를 적재한다.
이때 함께 점검할 항목:
- 누락 파일
- 중복 매핑
- 퇴사자 데이터
- 이메일 변경 이력
### 6-5. 조회 인터페이스 설계
신규앱이 파일명을 직접 조합하지 않도록 조회 endpoint를 `photoLookupKey` 기준으로 고정한다.
후보:
- `GET /profile-images/{photo_lookup_key}`
- `GET /profile-image?key=...`
둘 다 의미는 비슷하지만, 경로형인 `GET /profile-images/{photo_lookup_key}`가 더 읽기 쉽고 관리가 단순하므로 우선안으로 본다.
### 6-6. 조회 인터페이스를 쉽게 설명하면
앱은 더 이상 `"kimss.jpg"` 같은 실제 파일명을 만들지 않는다.
대신 아래처럼 `photoLookupKey`만 전달한다.
```http
GET /profile-images/a8f3x91k...
```
또는
```http
GET /profile-image?key=a8f3x91k...
```
그러면 외부서버가 내부적으로:
1. 전달받은 key를 테이블에서 찾고
2. 그 key에 연결된 실제 이미지 파일을 찾고
3. 그 이미지를 앱에 대신 내려준다
즉, 앱은 파일명을 모르고도 이미지를 볼 수 있다.
### 6-7. 이미지 응답 방식 결정
응답 방식은 아래 두 가지가 있다.
1. 이미지 바이너리 직접 응답
외부서버가 JPEG 또는 PNG 자체를 바로 응답한다.
2. CDN 또는 실제 파일 URL로 redirect
외부서버가 내부 검증 후 다른 이미지 주소로 이동시키는 방식이다.
1차 구현 우선안:
- `GET /profile-images/{photo_lookup_key}`
- 이미지 바이너리 직접 응답
이유:
- 구조가 단순하다
- 파일 실제 위치를 숨기기 쉽다
- 앱 쪽 구현이 단순하다
### 6-8. 접근 통제와 운영 정책
`photoLookupKey`만 알면 누구나 무제한 조회되는 구조는 피해야 한다.
정리 필요 항목:
- 앱 또는 API gateway 기준 인증 필요 여부
- rate limit
- 캐시 헤더
- 만료 정책
- 비정상 대량 조회 탐지
### 6-9. 갱신 절차 정의
아래 이벤트 발생 시 테이블과 이미지 자산이 어떻게 갱신되는지 운영 절차를 정리한다.
- 입사
- 퇴사
- 이메일 변경
- 사진 교체
- 사용자 정보 정정
## 7. 신규앱 측 단계별 작업
### 7-1. 현재 DTO 식별 필드 점검
직원검색, 조직도, 직원 상세 응답에서 어떤 식별값을 안정적으로 받을 수 있는지 먼저 확인한다.
최소 확인 대상:
- 네이버웍스 사진 URL 또는 네이버웍스 사진 존재 여부를 나타내는 필드
- `email`
- `emailLocalPart`
- `photoLookupKey`
추가 전제:
- 전달 예정인 네이버웍스 연동용 개발자계정으로 실제 프로필 사진 조회 가능 여부와 응답 구조를 먼저 확인한다.
### 7-2. 계약 보강 포인트 정리
현재 DTO에 프로필 사진 매핑용 안정 식별자가 없으면 아래 중 하나를 계약 보강 후보로 요청한다.
- `naverWorksPhotoUrl` 또는 이에 준하는 사진 필드
- `email`
- `emailLocalPart`
- `photoLookupKey`
우선 확인안은 `네이버웍스 사진 식별/URL 제공 가능 여부`이고, 외부서버 fallback용으로는 `photoLookupKey` 직접 제공이 권고안이다.
### 7-3. 앱 내부 매핑 전략 확정
가능한 방식은 두 가지다.
1. 서버/DTO가 `photoLookupKey`를 직접 내려주고 앱은 그 값만 사용
2. 앱이 직원 식별값을 받아 직접 `photoLookupKey`를 계산
권고안은 1번이다.
이유:
- 앱이 원본 식별값을 덜 알게 된다
- 해시/HMAC 규칙을 앱에 넣지 않아도 된다
- 보안 검토 범위가 줄어든다
- 앱 구현이 단순해진다
### 7-4. 이미지 조회 규칙 반영
앱은 아래 우선순위 규칙으로 이미지를 선택한다.
1. 네이버웍스 사진이 있으면 그것을 사용
2. 네이버웍스 사진이 없으면 외부서버 `photoLookupKey` 기반 이미지 조회
3. 둘 다 없으면 앱 기본 아바타 사용
앱은 외부서버 fallback 단계에서도 더 이상 `이메일 @ 앞부분.jpg`를 붙여 이미지 URL을 만들지 않는다.
대신 아래와 같은 고정 규칙만 사용한다.
```text
/profile-images/{photo_lookup_key}
```
### 7-5. fallback 처리
아래 상황에서는 기본 아바타를 노출한다.
- 네이버웍스 사진 없음
- `photoLookupKey` 없음
- 외부서버 404
- timeout
- 기타 이미지 로드 실패
중요 원칙:
- 프로필 사진 실패 때문에 직원검색/조직도 본문 로딩이 깨지지 않도록 분리 처리한다
### 7-6. 캐시와 placeholder 정책
동일 이미지가 목록에서 반복 노출될 수 있으므로 앱 이미지 캐시 정책과 placeholder 표현을 함께 정리한다.
### 7-7. 테스트 시나리오
- 네이버웍스 사진이 있으면 외부서버 조회 없이 우선 노출되는지 확인
- 네이버웍스 사진이 없고 `photoLookupKey`가 있으면 외부서버 사진이 노출되는지 확인
- 네이버웍스 사진도 없고 `photoLookupKey`도 없으면 기본 이미지가 노출되는지 확인
- `photoLookupKey`가 있을 때 정상 이미지 노출
- `photoLookupKey`가 없을 때 기본 이미지 노출
- 외부서버 404 시 fallback 유지
- 응답 지연 또는 timeout 시 본문 기능 유지
- 잘못된 이미지가 다른 직원에게 매핑되지 않는지 확인
## 8. 현재 권고안
현재 시점의 우선 권고안은 아래와 같다.
1. 신규앱의 프로필 사진 1순위 소스는 네이버웍스로 둔다.
2. 네이버웍스 사진이 없을 때만 외부서버 `photoLookupKey -> 실제 이미지` 매핑 테이블을 사용하는 fallback 경로로 내려간다.
3. 외부서버는 `GET /profile-images/{photo_lookup_key}` 형태의 조회 endpoint를 제공한다.
4. 1차 구현은 외부서버가 이미지를 직접 응답하는 방식으로 시작한다.
5. 신규앱은 파일명을 직접 만들지 않는다.
6. 공유 예정인 네이버웍스 개발자계정으로 연동 가능성과 필요한 API/권한 범위를 먼저 확인한다.
7. 직원 DTO 또는 별도 프로필 응답에 `네이버웍스 사진 필드``photoLookupKey`를 함께 포함시킬 수 있는지 우선 검토한다.
## 9. 후속 확인 필요 항목
- 공유 예정인 네이버웍스 개발자계정의 권한 범위가 프로필 사진 조회에 충분한지
- 네이버웍스 연동 시 앱이 직접 API를 호출하는지, Baron SSO 또는 중간 서버가 사진 URL/바이너리를 전달하는지
- Baron SSO 연계 응답 또는 직원 API에서 네이버웍스 사진 URL/식별값을 받을 수 있는지
- 네이버웍스 사진이 없는 사용자를 어떤 기준으로 판별할 수 있는지
- Baron SSO 또는 직원 API 응답에 `email`이 항상 존재하는지
- `email local-part`가 전사적으로 유일하고 장기적으로 안정적인지
- 이메일 변경 시 파일명과 매핑 테이블을 어떻게 갱신할지
- 외부서버가 앱 전용 이미지 조회 endpoint를 제공할 수 있는지
- 이미지 직접 응답과 CDN redirect 중 어느 운영 방식이 더 적합한지
- 직원 DTO에 `photoLookupKey`를 직접 추가할 수 있는지
## 10. 관련 문서
- `docs/00_guide_tdc114plus_work_progress_timetable_2026-07-02.md`
- `docs/00_guide_tdc114plus_org_context_mapping_2026-07-08.md`
- `docs/00_contract_tdc114plus_api_2026-07-02.md`