자유롭게 사용 가능한 API: 자체 포함 키와 요청 제한 기능
개발자들은 면접에서 localStorage나 jsonplaceholder 데이터를 활용해 프론트엔드 앱을 선보이는 경우가 많습니다. 서버 비용 없이 개발이 가능하지만, 정적 데이터와 setTimeout을 통한 인위적인 지연만 제공됩니다. 더 나은 대안은? 실제 API를 제공하는 플랫폼으로, 자신만의 데이터를 업로드할 수 있는 환경입니다. 설정은 단 몇 분 안에 끝나며 백엔드 구축이 필요 없습니다.
아키텍처는 웹 인터페이스에 Next.js(SSG)를 사용하고, 사용자 및 키 관리를 위해 Node.js/Express를 활용하며, 별도의 API 서비스를 운영합니다. 모든 구성 요소는 Docker로 실행되며, Nginx 프록시를 통해 연결됩니다.
무료 접근의 문제점과 API 키 해결책
제한 없이 누구나 스팸 요청으로 시스템을 과부하할 수 있습니다. 핵심 전략은 데이터베이스 쿼리 횟수를 최소화하고, 키 검증 시점에서 유효하지 않은 키를 미리 차단하는 것입니다.
키는 자체 포함 형식으로, ppk_version_userId_nonce_signature 형태로 구성됩니다. 인증 방식은 다음과 같습니다: Authorization: PetProjects ppk_v1_1_nonce_signature.
검증은 두 단계로 진행됩니다:
- 로컬 검증: 데이터베이스에 접근하지 않고도 구조와 HMAC 서명을 확인합니다.
- 데이터베이스 조회: 초기 유효성 검사 통과 후에만 userId를 조회합니다.
function validateApiKey(apiKey: string): ApiKeyPayload | null {
if (!apiKey.startsWith('ppk_')) return null;
const parts = apiKey.split('_');
if (parts.length !== 5) return null;
const [, version, userIdRaw, nonce, signature] = parts;
const userId = Number(userIdRaw);
if (!Number.isInteger(userId)) return null;
if (!signature || !/^[a-f0-9]{64}$/.test(signature)) return null;
const payload = `${version}.${userId}.${nonce}`;
const expectedSignature = crypto.createHmac('sha256', API_KEY_SECRET).update(payload).digest('hex');
if (signature.length !== expectedSignature.length) return null;
const isValid = crypto.timingSafeEqual(Buffer.from(signature, 'hex'), Buffer.from(expectedSignature, 'hex'));
if (!isValid) return null;
return { version, userId, nonce };
}
timingSafeEqual는 타이밍 공격을 방지합니다. 유효한 키는 LRUCache(최대 10,000개 항목, TTL 5분)에 캐시됩니다.
캐싱과 성능 균형 잡기
캐싱은 지연 시간을 줄이고 데이터베이스 부담을 낮춥니다. 5분의 TTL은 일정한 트레이드오프입니다: 유출된 키는 만료될 때까지 계속 유효합니다. 이후 재인증이 필요합니다.
한계점:
- 즉각적인 키 무효화 불가
- 유출된 키는 TTL 만료 전까지 유효함
- 비밀키 보호 필수
향후 개선 방향: 블랙리스트 지원, 키 버전 관리, 동적 무효화 기능 등이 가능합니다.
API 테스트를 위한 실습 환경
브라우저에서 직접 요청을 보내고, 자동으로 키가 채워지는 인터랙티브 인터페이스를 제공합니다. 다양한 언어별 코드 예제도 자동 생성됩니다.
예시 POST 요청:
curl -L -X POST 'https://api.pet-projects.io/rest/free' \
-H 'Authorization: PetProjects ppk_v1_1_a1b2c3d4e5_a1b2c3d4e5f6g7h8i10j11' \
-H 'Content-Type: application/json' \
-d '{
— Editorial Team
아직 댓글이 없습니다.