인증 · API 키
MoonPD 외부 API·MCP는 API 키(Bearer/X-API-Key) 또는 OAuth 2.0 PKCE로 인증합니다.
API 키 발급
1
로그인 후 마이페이지
2
키 발급
키 이름·스코프 입력 후 발급. secret은 발급 시 1회만 표시되니 안전한 곳에 보관하세요.
3
이후 마스킹
목록에는 키 prefix(앞 12자)만 표시됩니다.
키 형식
mpd_AbCdEfGhIjKlMnOpQrStUvWxYz0123456789AbCd
mpd_ 접두사 + Base64URL 32바이트 랜덤. 서버는 SHA-256 해시만 저장하며, 원본 secret은 저장하지 않습니다.
스코프
| 스코프 | 허용 동작 |
|---|---|
ebook:read | 이북 목록·상세·통계 조회 |
ebook:write | 이북 업로드·변환·메타 수정 |
ebook:publish | 이북 게시·공개 범위 변경·삭제 |
channel:read | 채널 조회 |
channel:write | 채널 소개·프로필 수정 |
stats:read | 대시보드·통계 조회 |
shorturl:read | 내가 발급한 단축 URL 조회·목록·클릭 통계 |
shorturl:write | 단축 URL 발급·비활성화 (mpd.zip/M{6}) |
기본값은 ebook:read, ebook:write, stats:read입니다. 게시·삭제, 단축 URL은 별도 스코프가 필요합니다. 발급 후에도 마이페이지 > API 키에서 스코프 수정 가능 — 변경 이력은 감사 로그에 자동 기록됩니다.
OAuth 2.0 (Authorization Code + PKCE)
Claude.ai 웹 등 MCP 클라이언트를 사용자 계정에 연결할 때 사용합니다. 인가 코드 + PKCE(S256) 흐름으로, 사용자 동의를 거쳐 access_token을 발급받습니다.
OAuth 앱 발급
1
마이페이지 접속
로그인 후 마이페이지 → MCP·API 탭으로 이동합니다.
2
OAuth 앱 발급
OAuth 앱 발급 버튼을 누르면 Key ID와 Key Secret이 발급됩니다. 필요 시 custom redirect_uri를 함께 등록할 수 있습니다(옵션).
3
자격증명 보관
Key Secret은 발급 시 1회만 표시됩니다. 안전한 곳에 보관하세요. 분실 시 재발급해야 합니다.
| 자격증명 | OAuth 파라미터 | 형식 |
|---|---|---|
| Key ID | client_id | mpdc_... |
| Key Secret | client_secret | mpds_... (1회 노출) |
엔드포인트
| 엔드포인트 | 설명 |
|---|---|
GET /api/v1/oauth/authorize | 로그인·동의 → 인가 코드 발급 |
POST /api/v1/oauth/token | code + code_verifier → access_token |
POST /api/v1/oauth/revoke | 토큰 폐기 |
1. PKCE 준비
클라이언트는 랜덤한 code_verifier(43~128자)를 생성하고, 그 SHA-256 해시를 Base64URL로 인코딩해 code_challenge를 만듭니다(code_challenge_method=S256).
# code_verifier 생성 (예시)
code_verifier=$(openssl rand -base64 60 | tr -d '\n=+/' | cut -c1-64)
# code_challenge = BASE64URL( SHA256( code_verifier ) )
code_challenge=$(printf '%s' "$code_verifier" \
| openssl dgst -binary -sha256 \
| openssl base64 | tr '+/' '-_' | tr -d '=')
2. 인가 요청 (authorize)
사용자를 아래 URL로 보냅니다. 로그인·동의 후 redirect_uri로 code와 state가 전달됩니다.
GET https://moonpd.ai/api/v1/oauth/authorize
?client_id={KeyID}
&redirect_uri={등록된 redirect_uri}
&code_challenge={code_challenge}
&code_challenge_method=S256
&scope=ebook:read ebook:write stats:read
&state={CSRF 방지용 임의 문자열}
# 동의 후 리다이렉트
{redirect_uri}?code=AUTH_CODE&state={state}
3. 토큰 교환 (token)
발급받은 code와 code_verifier를 application/x-www-form-urlencoded로 전송해 토큰을 받습니다.
curl -X POST https://moonpd.ai/api/v1/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=AUTH_CODE" \
-d "code_verifier=${code_verifier}" \
-d "client_id={KeyID}" \
-d "client_secret={KeySecret}" \
-d "redirect_uri={등록된 redirect_uri}"
{
"access_token": "...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "ebook:read ebook:write stats:read"
}
4. API 호출
발급된 access_token은 기존 API 키와 동일하게 Authorization: Bearer 헤더로 /api/v1/* 호출에 사용합니다.
curl https://moonpd.ai/api/v1/ebooks \
-H "Authorization: Bearer {access_token}"
토큰 폐기 (revoke)
curl -X POST https://moonpd.ai/api/v1/oauth/revoke \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "token={access_token}"
redirect_uri 정책
- Claude.ai 등 알려진 MCP 클라이언트의 callback URL은 기본 허용됩니다.
- 그 외 자체 클라이언트는 앱 발급 시 등록한 redirect_uri만 허용되며, 요청 값과 정확히 일치해야 합니다.
Key Secret은 서버 측에서만 사용하세요. 토큰 교환은 신뢰할 수 있는 백엔드에서 수행하고, state로 CSRF를 반드시 방지하세요.
보안 권고
- API 키를 GitHub 등 공개 저장소에 커밋하지 마세요. .env는 .gitignore에 포함.
- 운영 환경은 NCP Secret Manager 또는 GitHub Encrypted Secrets 사용.
- 분실·유출 의심 시 즉시 폐기 후 재발급.
- 스코프는 필요한 최소만 부여. 게시·삭제 권한은 분리 키로 관리.