워드프레스 REST API는 워드프레스를 헤드리스 CMS(headless CMS)로 쓸 수 있게 해 주는 공식 인터페이스입니다. 모바일 앱, React/Vue 프론트엔드, 외부 자동화 스크립트가 워드프레스의 글·페이지·사용자 정보를 JSON으로 주고받을 수 있죠. 이 글에서는 실제 운영 중인 WordPress 사이트를 기준으로 엔드포인트 구조, 인증 방법, 실전 예제 3가지를 정리합니다.
REST API 기본 엔드포인트 구조
워드프레스 REST API의 루트 경로는 /wp-json/wp/v2/ 입니다. 브라우저에서 바로 열어도 JSON 응답이 나옵니다.
# 사이트에 어떤 엔드포인트가 열려 있는지 확인
curl https://example.com/wp-json/
# 공개 글 목록 조회 (최근 10개)
curl https://example.com/wp-json/wp/v2/posts
# 특정 글 하나 조회
curl https://example.com/wp-json/wp/v2/posts/123
# 카테고리 목록
curl https://example.com/wp-json/wp/v2/categories
# 검색 (title, content 전체 검색)
curl "https://example.com/wp-json/wp/v2/posts?search=워드프레스"
| 엔드포인트 | 용도 | 인증 필요 |
|---|---|---|
| GET /wp/v2/posts | 글 목록 조회 | 공개 글은 불필요 |
| POST /wp/v2/posts | 새 글 작성 | 필요 |
| PUT /wp/v2/posts/{id} | 글 수정 | 필요 |
| DELETE /wp/v2/posts/{id} | 글 삭제(휴지통) | 필요 |
| GET /wp/v2/media | 미디어 라이브러리 조회 | 공개 미디어만 불필요 |
| GET /wp/v2/users/me | 내 정보 조회 | 필요 |
인증 방법 — Application Passwords가 가장 쉽다
글 작성·수정처럼 권한이 필요한 작업은 인증이 있어야 합니다. WordPress 5.6부터 기본 내장된 Application Passwords가 가장 간편합니다. 별도 플러그인 없이도 됩니다.
Application Password 발급 절차
- WP 관리자 → 사용자 → 프로필
- 하단 “애플리케이션 비밀번호” 섹션 이동
- 이름 입력 (예:
my-mobile-app) → “새 애플리케이션 비밀번호 추가” - 화면에 나오는 24자리 비밀번호를 복사 (한 번만 표시됨)
curl로 Basic Auth 호출
# 새 글 작성
curl -X POST https://example.com/wp-json/wp/v2/posts \
-u "myuser:xxxx xxxx xxxx xxxx xxxx xxxx" \
-H "Content-Type: application/json" \
-d '{
"title": "REST API로 작성한 글",
"content": "<p>자동으로 올라간 글입니다.</p>",
"status": "publish",
"categories": [1]
}'
⚠️ Application Password는 토큰이라 노출되면 누구나 계정을 탈취할 수 있습니다. Git에 올리지 말고, 서버 환경변수(.env)에 저장하세요.
실전 활용 예제 3가지
① Python 스크립트로 글 자동 발행
import os, requests
from requests.auth import HTTPBasicAuth
WP_URL = "https://example.com/wp-json/wp/v2"
auth = HTTPBasicAuth(os.environ["WP_USER"], os.environ["WP_APP_PASS"])
def create_post(title, content, categories=None, tags=None):
payload = {
"title": title,
"content": content,
"status": "publish",
"categories": categories or [],
"tags": tags or [],
}
r = requests.post(f"{WP_URL}/posts", auth=auth, json=payload, timeout=10)
r.raise_for_status()
return r.json()
post = create_post(
title="오늘의 주가 요약",
content="<p>KOSPI가 전일 대비 1.2% 올랐습니다.</p>",
categories=[7], # 재테크/금융
)
print(f"Published: {post['link']}")
② JavaScript(Node.js)로 이미지 업로드
import fs from "node:fs";
const user = process.env.WP_USER;
const pass = process.env.WP_APP_PASS;
const auth = Buffer.from(`${user}:${pass}`).toString("base64");
const file = fs.readFileSync("./cover.jpg");
const res = await fetch("https://example.com/wp-json/wp/v2/media", {
method: "POST",
headers: {
"Authorization": `Basic ${auth}`,
"Content-Type": "image/jpeg",
"Content-Disposition": 'attachment; filename="cover.jpg"',
},
body: file,
});
const media = await res.json();
console.log("Uploaded media ID:", media.id);
③ React 프론트엔드에서 글 목록 렌더링
import { useEffect, useState } from "react";
export function LatestPosts() {
const [posts, setPosts] = useState([]);
useEffect(() => {
fetch("https://example.com/wp-json/wp/v2/posts?per_page=5&_embed")
.then(r => r.json())
.then(setPosts);
}, []);
return (
<ul>
{posts.map(p => (
<li key={p.id}>
<a href={p.link}>{p.title.rendered}</a>
</li>
))}
</ul>
);
}
_embed 파라미터를 붙이면 작성자·대표 이미지 등 연관 정보까지 한 번에 가져옵니다. N+1 요청을 막아주니 프론트에서 유용합니다.
자주 만나는 에러와 해결
| 에러 | 원인 / 해결 |
|---|---|
rest_no_route | 경로 오타 또는 permalinks가 “기본” 설정 → 설정 → 고유주소에서 “포스트 이름”으로 변경 후 저장 |
rest_cannot_create | 인증 사용자에게 권한 없음 (작성자 이상 역할 필요) |
401 Unauthorized | Application Password 오타 / 공백 포함 여부 확인 |
403 Forbidden | Wordfence/보안 플러그인이 REST API 차단 → 허용 목록에 API 경로 추가 |
| Nginx에서 404 | try_files $uri $uri/ /index.php?$args; 규칙 누락 |
보안 체크리스트
- ✅ 외부 앱 하나당 별도의 Application Password를 발급해 회수·감사가 쉽게
- ✅ 노출되면 즉시 해당 Application Password 폐기 (프로필에서 삭제)
- ✅ 공용 WiFi에서 관리 계정으로 호출 금지 — 반드시 HTTPS 사용
- ✅ 운영 사이트는
/wp-json/wp/v2/users같은 민감 엔드포인트를 필요 시 disable REST API 플러그인으로 차단 - ✅ Cloudflare / Wordfence 룰로 IP 제한이 가능하면 활용
FAQ
Q. REST API를 완전히 끄고 싶어요. 안전한가요?
일부 플러그인(블록 에디터, Site Kit, Yoast 등)이 내부적으로 REST API를 씁니다. 전부 차단하면 관리자 화면이 깨질 수 있으니, 비로그인 사용자만 차단하는 식의 부분 제한을 권장합니다.
Q. JWT Auth가 더 낫다는데 꼭 써야 하나요?
Application Passwords는 Basic Auth 기반이라 매 요청에 토큰이 실립니다. 짧게 만료되는 세션이 필요하거나 모바일 앱에서 로그인 화면을 쓰고 싶다면 JWT Auth 플러그인이 낫습니다. 백엔드 자동화용이라면 Application Password로 충분합니다.
Q. 호출 속도가 너무 느립니다.
무거운 플러그인이 매 요청마다 초기화되기 때문입니다. Nginx 레벨에서 fastcgi_cache로 공개 GET 요청을 캐싱하면 극적으로 빨라집니다. 단, 인증이 필요한 POST/PUT 요청은 캐시에서 제외하도록 $skip_cache 규칙을 추가하세요.
마무리
REST API는 워드프레스를 단순 블로그에서 데이터 허브로 확장해 주는 열쇠입니다. 처음에는 Application Password + curl 조합으로 실험해 보고, 점차 Python/Node 스크립트로 발전시키는 흐름을 추천합니다. 운영 중인 사이트라면 반드시 HTTPS + IP 제한 + 앱별 별도 패스워드 세 가지만 지켜도 사고 확률이 크게 줄어듭니다.