CloudFlare
Category: How-To Guide
Overview
In this guide, you’ll learn how to build a server-side paywall using Pelcro and Cloudflare Workers to securely enforce content access at the edge.
You’ll use Pelcro’s Authentication and Authorization APIs to:
- Identify logged-in users from their Pelcro token.
- Retrieve the user resource.
- Verify the user’s entitlements before serving premium content.
By the end, you’ll have a working Cloudflare Worker that authenticates a Pelcro user, checks their subscription, and conditionally serves or blocks content.
Prerequisites
- A Pelcro tenant with API access (server-side key).
- A Cloudflare account with Workers and KV storage enabled.
- A CMS that adds
X-Access-TierandX-Content-Idheaders per page.
Step 1 — Understand the Flow
A server-side paywall runs before your content is served. Cloudflare Workers intercept the request, validate the user’s Pelcro token, and call Pelcro APIs to check entitlements.
User → Cloudflare Worker → Pelcro API (auth + entitlements) → CMS (content)
If the user is entitled, the Worker lets the request continue to your CMS. Otherwise, it blocks or shows a preview.
Step 2 — Authenticate the User via Pelcro
According to Pelcro’s Authenticate a Customer recipe, you can retrieve a user’s information using their token.
After login on your site, Pelcro sets a cookie like:
pelcro_session=<JWT_TOKEN>
Inside your Worker, extract the token and call the Pelcro Open API /user endpoint:
async function getUserFromPelcro(apiBase, token) {
const res = await fetch(`${apiBase}/user`, {
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
});
if (!res.ok) return null;
const data = await res.json();
return data.data; // returns the Pelcro user resource
}Response Example:
{
"data": {
"id": 12345,
"email": "[email protected]",
"subscriptions": [ { "plan_id": 6789, "status": "active" } ]
}
}✅ Tip: Store your PELCRO_API_URL (e.g., https://www.pelcro.com/) as an environment variable or Worker Secret.
Step 3 — Check Entitlements
Following Pelcro’s Authorization recipe, you can verify whether the user has access to a specific resource (content, tier, or plan).
You’ll call the /authorization endpoint to check entitlement state:
async function checkEntitlement(apiBase, token, resourceType, resourceId) {
const res = await fetch(`${apiBase}/authorization`, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
data: {
type: "authorization",
attributes: {
resource_type: resourceType,
resource_id: resourceId
}
}
})
});
const data = await res.json();
return data.data.attributes.allowed; // true or false
}Example Request:
{
"data": {
"type": "authorization",
"attributes": {
"resource_type": "content",
"resource_id": "article-123"
}
}
}Example Response:
{
"data": {
"type": "authorization",
"id": "12345",
"attributes": {
"allowed": true
}
}
}Step 4 — Combine Authentication and Authorization in the Worker
Here’s how the complete Cloudflare Worker ties everything together:
export default {
async fetch(req, env) {
const url = new URL(req.url);
const cookies = parseCookies(req.headers.get("Cookie") || "");
const token = cookies["pelcro_session"];
const accessTier = req.headers.get("X-Access-Tier") || "standard";
const contentId = req.headers.get("X-Content-Id") || url.pathname;
// Step 1: Authenticate
const user = await getUserFromPelcro(env.PELCRO_API_URL, token);
// Step 2: Check entitlement
const allowed = user
? await checkEntitlement(env.PELCRO_API_URL, token, "content", contentId)
: false;
// Step 3: Enforce paywall
if (allowed || accessTier === "free") {
return fetch(req);
}
// Not allowed — redirect to Pelcro offers
return Response.redirect("https://yourdomain.com/subscribe", 302);
}
};
function parseCookies(str) {
return Object.fromEntries(str.split(";").map(v => v.trim().split("=")).filter(p => p[0]));
}✅ Note: This Worker enforces the paywall server-side, so users cannot bypass access control by disabling JavaScript.
Step 5 — Deploy
- Save your Worker code.
- Store
PELCRO_API_URLas a secret:npx wrangler secret put PELCRO_API_URL - Deploy your Worker:
npx wrangler publish
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
401 Unauthorized | Token expired or missing | Confirm Pelcro cookie (pelcro_session) is present and valid |
| Content cached incorrectly | Missing cache variation by entitlement | Add Vary: X-Access-State header in Worker |
| Slow responses | Entitlement API not cached | Use Cloudflare KV to store entitlement results for a few minutes |
Next Steps
- Pelcro API Reference – Authentication
- Pelcro API Reference – Authorization
- Pelcro Paywall Enforcement Overview
- Cloudflare Workers Documentation
Summary
You’ve successfully implemented a server-side paywall using Cloudflare Workers and Pelcro APIs. Your Worker now:
- Authenticates users with their Pelcro session token.
- Verifies entitlements for each content request.
- Enforces paywall logic before the CMS responds.
This design keeps premium content secure, improves performance, and provides a scalable integration pattern for publishers using Zephyr or Naviga with Pelcro.
Updated 1 day ago
