콘텐츠로 이동

Cloudflare 개발자 가이드

Cloudflare 패키지는 렌더링을 Worker 경계로 옮깁니다. Worker 렌더링, 로컬 폴백, API 보호, R2 아카이브는 각각 독립적인 실패 처리가 필요한 별도 기능으로 다루어야 합니다.

엣지 렌더링 서비스, 보호된 렌더 엔드포인트, 아카이브 워크플로, 로컬 폴백 경로를 nextpdf/cloudflare 기반으로 구축할 때 이 가이드를 참고합니다.

계층담당책임여기에 두지 말 것
애플리케이션 엔드포인트애플리케이션호출자를 인가하고, 렌더 요청을 정규화하며, 비즈니스 정책을 적용합니다.코드에 Worker 토큰을 저장하는 것.
API 보호nextpdf/cloudflare 및 애플리케이션API 키, 페이로드 크기, 프로세스 내 속도 제한을 결정합니다.청구, 테넌트 권한 또는 지속적 할당량 적용.
Cloudflare 렌더러nextpdf/cloudflareHTML 및 Worker URL을 검증하고, 렌더 페이로드를 전송하며, 응답을 파싱합니다.템플릿 렌더링이나 도메인 쿼리.
Worker (워커)애플리케이션 배포Browser Rendering을 실행하고 PDF 바이트 또는 구조화된 결과를 반환합니다.PHP 측 저장 정책.
로컬 폴백애플리케이션 배포Worker를 사용할 수 없을 때 렌더링합니다.운영 장애를 숨기는 자동 폴백.
R2 아카이브nextpdf/cloudflarePDF를 업로드하고, 객체 키를 구성하며, 서명된 URL을 생성합니다.검토되지 않은 민감한 비즈니스 메타데이터.
단계동작개발자 작업
구성 생성Worker URL, API 토큰, 타임아웃, 크기 제한, 폴백 및 핀이 로드됩니다.비밀값은 배포 구성에 보관해야 합니다.
요청 보호선택적 ApiProtection이 키, 크기 및 속도 제한을 검증합니다.비용이 많이 드는 렌더 작업 이전에 실행해야 합니다.
렌더러 호출CloudflareHtmlRenderer가 HTML 및 Worker URL을 검증한 다음 JSON을 전송합니다.Worker를 사용할 수 없는 경우와 렌더 실패를 별도로 처리해야 합니다.
응답 파싱CloudflareResponseParser::parse()는 바이너리 PDF 또는 구조화된 JSON 출력을 받아들입니다.유효하지 않거나 PDF가 아닌 출력은 거부해야 합니다.
로컬 폴백선택적 로컬 렌더러가 Worker 실패를 처리합니다.호스트가 지원하는 경우에만 로컬 렌더러 팩토리를 주입해야 합니다.
R2 아카이브R2ArchiveManager는 PDF 바이트를 저장하고 서명된 URL을 생성합니다.명시적으로 저장하기로 한 경우가 아니라면 메타데이터에는 민감한 값을 넣지 않아야 합니다.
경로용도
app/Pdf/Cloudflare/*CloudflareHtmlRenderer를 감싸는 애플리케이션 래퍼입니다.
app/Pdf/Workers/*Worker 요청 DTO와 엔드포인트별 정책입니다.
app/Pdf/Archive/*R2 아카이브 오케스트레이션 및 보존 결정입니다.
app/Pdf/Fallback/*폴백이 허용될 때 사용하는 LocalRendererFactoryInterface 구현입니다.
tests/Pdf/Cloudflare/*Worker 다운, 잘못된 토큰, 페이로드, 아카이브 테스트입니다.

PHP API 토큰과 Worker 토큰은 분리해 유지해야 합니다. PHP 측은 Worker에 인증합니다. Worker는 브라우저 작업을 수행하기 전에 들어오는 요청을 인증해야 합니다.

<?php
use NextPDF\Cloudflare\ApiProtection;
use NextPDF\Cloudflare\ApiProtectionConfig;
use NextPDF\Cloudflare\ApiKeyValidator;
$protection = new ApiProtection(
new ApiProtectionConfig(maxRequestsPerMinute: 30),
new ApiKeyValidator([$expectedApiKey]),
);
$result = $protection->checkRequest(
clientId: $clientId,
payloadSize: strlen($html),
apiKey: $presentedApiKey,
);
if (!$result->allowed) {
return new JsonResponse(['error' => $result->denialReason], 429, $result->toHeaders());
}

프레임워크의 PSR-18 및 PSR-17 의존성을 사용해 렌더러를 구축합니다. 시스템이 Worker 사용을 중단한 시점을 운영자가 확인할 수 있도록 로컬 폴백은 명시적으로 유지합니다.

<?php
use NextPDF\Cloudflare\CloudflareHtmlRenderer;
use NextPDF\Cloudflare\CloudflareRendererConfig;
$renderer = new CloudflareHtmlRenderer(
config: CloudflareRendererConfig::fromArray([
'worker_url' => getenv('NEXTPDF_CLOUDFLARE_WORKER_URL'),
'api_token' => getenv('NEXTPDF_CLOUDFLARE_API_TOKEN'),
'render_timeout' => 30,
'max_html_size' => 1_000_000,
'fallback_to_local' => false,
]),
httpClient: $httpClient,
requestFactory: $requestFactory,
streamFactory: $streamFactory,
);
$rendered = $renderer->render($html, widthPt: 595.28);

렌더링이 성공하고 정책이 승인된 이후에만 아카이브합니다. 공개 URL과 서명된 URL은 별도의 결정으로 취급합니다.

<?php
use NextPDF\Cloudflare\R2ArchiveManager;
$upload = $archive->upload(
pdfData: $rendered->pdfData,
filename: 'invoice-1234.pdf',
metadata: [
'document_type' => 'invoice',
],
);
if ($upload->isValid()) {
$temporaryUrl = $archive->generateSignedUrl($upload->key, 600);
}

보존 및 접근 정책에서 명시적으로 허용하지 않는 한, 고객 이름, 이메일 주소, 인보이스 총액 또는 규제 대상 식별자를 객체 메타데이터에 넣지 않아야 합니다.

확장 지점용도제약
LocalRendererFactoryInterfaceArtisan 또는 다른 렌더러로 로컬 폴백합니다.반드시 LocalRendererInterface를 구현하는 객체를 반환해야 합니다.
ApiProtectionConfigAPI 키, 페이로드 크기, 속도 제한 정책입니다.인메모리 제한은 프로세스별로 적용됩니다.
ApiKeyValidator타이밍 안전 키 검증과 키 회전 헬퍼입니다.비밀값은 소스 코드 외부에 저장해야 합니다.
R2ArchiveConfig버킷, 자격 증명, 경로 접두사, 엔드포인트, 크기 제한입니다.자격 증명은 절대 로그에 기록해서는 안 됩니다.
PinnedCurlTransportIP 및 SPKI 핀을 적용합니다.cURL을 지원하는 런타임과 응답 팩토리가 필요합니다.
CloudflareResponseParserWorker 응답을 파싱합니다.유효하지 않은 PDF 또는 오류 응답을 거부합니다.
  1. 먼저 로컬 렌더 경로를 구축합니다.
  2. 대표적인 작은 HTML 픽스처로 Worker 렌더링을 추가합니다.
  3. 공개 엔드포인트를 노출하기 전에 요청 보호를 활성화합니다.
  4. 렌더 및 응답 흐름이 안정된 후에만 R2 업로드를 추가합니다.
  5. Worker 다운, 잘못된 토큰, 초과 크기 페이로드, 속도 제한, R2 실패 경로를 테스트합니다.
  6. Worker 렌더, 폴백 렌더, 아카이브 업로드, 서명된 URL 생성을 구분하는 로그를 추가합니다.
실패처리되어야 할 위치권장 대응
누락되거나 유효하지 않은 API 키API 보호 계층.렌더 작업이 시작되기 전에 거부합니다.
초과 크기 페이로드API 보호 또는 렌더러 검증.Worker 호출 없이 검증 실패를 반환합니다.
안전하지 않은 Worker URL렌더러 보안 정책.네트워크 I/O 전에 구성 또는 요청을 실패로 처리합니다.
Worker 사용 불가렌더러 경계.허용된 경우에만 명시적 폴백을 사용하고, 그렇지 않으면 가시적으로 실패시킵니다.
R2 업로드 실패아카이브 경계.아카이브가 선택 사항이면 PDF 응답을 반환하고, 정책상 아카이브가 필수이면 실패시킵니다.
핀 회전 실패배포 및 운영.백업 핀과 롤백 계획을 사용해 회전합니다.
고려 사항기본값재정의 시점
폴백구성 기본값으로 활성화됩니다.로컬 렌더링이 배포 격리를 위반하는 경우 비활성화합니다.
최대 HTML 크기5,000,000 바이트.공개 엔드포인트의 경우 낮춥니다.
서명된 URL TTL3600초.민감한 PDF의 경우 단축합니다.
핀 세트비어 있음.회전 계획과 백업 핀이 있을 때만 핀을 추가합니다.
API 키 요구 사항보호 구성 기본값으로 활성화됩니다.비공개이며 이미 인증된 내부 호출에 대해서만 비활성화합니다.
  • 렌더러 테스트는 유효한 HTML, 초과 크기 HTML, 유효하지 않은 Worker URL, Worker 오류 응답을 다룹니다.
  • API 보호 테스트는 키 누락, 잘못된 키, 너무 큰 페이로드, 속도 제한 초과를 다룹니다.
  • R2 테스트는 성공적인 업로드, 너무 큰 업로드, 실패한 HTTP 상태, 유효하지 않은 버킷, 서명된 URL 생성을 다룹니다.
  • 폴백 테스트는 로컬 렌더러 경로가 명시적이고 관찰 가능한지 검증합니다.
  • 전송 테스트는 고정 IP, 공개 키 핀, 타임아웃, 정책으로 비활성화된 리디렉션을 다룹니다.
  • 관찰 가능성 테스트는 렌더, 폴백, 아카이브, 서명된 URL 생성에 대해 별개의 로그 이벤트를 검증합니다.