# NAVER WORKS Refresh `unauthorized_client` 장애 및 재인증 복구 기록

**작성일**: 2026-02-27  
**작성자**: Codex  
**상태**: 완료 (재인증으로 복구 확인)

## 문제 요약

- `auth-server`의 `POST /auth/naverworks/passport/refresh`가 2026-02-27부터 반복 실패
- 에러 본문: `{"error":"unauthorized_client"...}`
- 증상 구간 동안 NAVER WORKS 토큰 갱신 성공 로그/DB 갱신이 중단됨

## 확인된 사실 (로그/DB 기준)

1. **시각 전환점 (KST 기준)**
- `2026-02-26 09:00`: refresh `200 OK`
- `2026-02-27 09:00`부터: 동일 user_id 요청이 즉시 `500` + `unauthorized_client`

2. **오류 원문**
- `{"error_description":"Failed to refresh token with request.","error":"unauthorized_client","error_uri":"See document on https://developers.worksmobile.com/docs/auth-oauth"}`

3. **DB 상태**
- 장애 중 `naverworks_token.updated_at`가 `2026-02-26 09:00:00+09`에서 멈춤
- 즉, 갱신 성공 이벤트가 없어 새 토큰 저장 자체가 발생하지 않음

4. **클라이언트 값 일치 확인**
- DB `oauth_config.client_id/client_secret`와 Console 표시값 일치 확인
- 단순 오타/환경변수 불일치 가능성은 낮음

## 원인 해석

- RFC 6749 Section 5.2 정의상 `unauthorized_client`는 "해당 클라이언트가 해당 grant type 사용 권한이 없음"을 의미
- 이번 패턴은 로컬 저장 로직 결함보다, NAVER WORKS 측에서 해당 클라이언트/권한부여 상태를 거부한 상태와 일치

## 실제 복구 절차

1. 사용자 재인증 URL 호출
- `GET /auth/naverworks/passport/install?user_id={uuid}&return_url=...`

2. 사용자 브라우저에서 NAVER WORKS 로그인/동의 완료

3. 즉시 refresh 재테스트
- `POST /auth/naverworks/passport/refresh?user_id={uuid}`

## 복구 검증 결과

- 재인증 직후 refresh 응답: `200 OK`
- 응답 본문: `{"success":true,...,"has_refresh_token":true}`
- DB `updated_at`: `2026-02-27 14:08:32+09`로 갱신 확인
- 결론: 재인증으로 토큰/권한부여 상태 정상화

## 왜 재인증이 효과적이었는가

- 기존 refresh 체인이 NAVER WORKS 측에서 거부되고 있었고,
- 재인증으로 새 authorization code/토큰 체인을 다시 발급받으면서 권한부여 상태가 회복됨

## 재발 시 즉시 체크리스트

1. `auth-server` 로그에서 `2/26 성공 -> 2/27 실패` 형태 전환점 확인
2. `naverworks_token.updated_at` 정지 여부 확인
3. Console의 `client_id/client_secret`와 DB `oauth_config` 일치 확인
4. 사용자 재인증 수행 후 refresh `200` 여부 확인
5. 재인증 후에도 실패 시 Console 감사로그(변경 이력) 및 NAVER WORKS 지원 문의

## 관련 근거

- RFC 6749 §5.2: `unauthorized_client` 정의
- NAVER WORKS OAuth 문서: token refresh 파라미터/흐름
- 서버 실측 로그: `auth-server` timestamps
- DB 실측: `main_db.naverworks_token.updated_at`

## 추가 운영 기록 (수동 재실행 중복 전송)

- 발생 시각(KST): `2026-02-27 14:26:48`, `14:27:03`
- 채널: `C09C98KK2TT`
- 상황: 수동 브리핑 검증 중 동일 작업을 2회 실행하여 브리핑 메시지 2건 전송
- 조치: 두 번째 메시지(`ts=1772170023.185609`)를 `chat.delete`로 즉시 삭제
- 검증: 삭제 API 응답 `ok: true`, 채널 최근 메시지 재조회 시 중복 해소 확인

## 교훈 (재발 방지)

1. 수동 실행 검증은 `1회 실행 -> 로그 확인 -> 추가 실행 여부 판단` 순서로 고정한다.
2. Slack 전송 테스트 전에는 "실전송 여부"를 먼저 명시하고, 재실행 전 사용자 확인을 받는다.
3. 중복 발생 시 즉시 대상 `channel/ts`를 특정해 두 번째 메시지만 삭제하고 결과를 기록한다.
