How to Take Screenshots of Password-Protected Pages (With Session Cookies)
You need to screenshot a protected page. Your dashboard. An admin panel. Paywalled content behind a login.
The problem: screenshot APIs don't have your login session. They see a redirect to /login instead of your dashboard.
The solution: pass your session cookies or Bearer token to the API.
Here's how to screenshot authenticated pages using the PageBolt API.
The Problem: Protected Pages Require Authentication
A raw API call to an authenticated page returns the login page:
curl -X POST https://api.pagebolt.dev/v1/screenshot \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/dashboard"}' \
> screenshot.png
# Result: screenshot of login page, not dashboard
The API doesn't have your cookies. It can't authenticate. It sees the login redirect.
You need to pass authentication data to the API.
Solution 1: Session Cookies
Extract your session cookie and pass it to the API:
// Get session cookie from your browser/app
// Example: "session_id=abc123def456; Path=/; HttpOnly"
const sessionCookie = 'session_id=abc123def456';
const payload = {
url: 'https://example.com/dashboard',
format: 'png',
cookies: [
{
name: 'session_id',
value: 'abc123def456',
domain: 'example.com'
}
]
};
const response = await fetch('https://api.pagebolt.dev/v1/screenshot', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PAGEBOLT_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
const buffer = await response.arrayBuffer();
That's it. The API authenticates using your cookie and returns the dashboard screenshot.
Real Example: Dashboard Screenshot with Session Cookie
// dashboard-screenshot.js
const https = require('https');
const fs = require('fs');
async function screenshotDashboard() {
// 1. Your app's session cookie
// In production, fetch this from your session store or database
const sessionCookie = 'session_id=abc123xyz789; path=/; domain=example.com';
// 2. Parse cookie
const [name, value] = sessionCookie.split('=').map(s => s.trim());
// 3. Send to PageBolt with cookie
const payload = JSON.stringify({
url: 'https://example.com/dashboard',
format: 'png',
width: 1920,
height: 1080,
fullPage: true,
cookies: [
{
name: name,
value: value.split(';')[0], // Remove path/domain suffix
domain: 'example.com'
}
]
});
const options = {
hostname: 'api.pagebolt.dev',
path: '/v1/screenshot',
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PAGEBOLT_API_KEY}`,
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(payload)
}
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let data = Buffer.alloc(0);
res.on('data', (chunk) => {
data = Buffer.concat([data, chunk]);
});
res.on('end', () => {
if (res.statusCode === 200) {
fs.writeFileSync('dashboard.png', data);
console.log('✓ Dashboard screenshot saved');
resolve(data);
} else {
reject(new Error(`API error ${res.statusCode}`));
}
});
});
req.on('error', reject);
req.write(payload);
req.end();
});
}
screenshotDashboard().catch(console.error);
Solution 2: Bearer Token Authentication
If your API uses Bearer token auth instead of cookies:
const payload = {
url: 'https://api.example.com/admin',
format: 'png',
headers: {
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
}
};
const response = await fetch('https://api.pagebolt.dev/v1/screenshot', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PAGEBOLT_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
Real Example: JWT Bearer Token
// api-screenshot-jwt.js
const https = require('https');
const fs = require('fs');
async function screenshotProtectedAPI() {
// Your JWT token (get from login endpoint or session store)
const jwtToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFkbWluIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
const payload = JSON.stringify({
url: 'https://api.example.com/admin-dashboard',
format: 'png',
width: 1280,
height: 720,
headers: {
'Authorization': `Bearer ${jwtToken}`,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
});
const options = {
hostname: 'api.pagebolt.dev',
path: '/v1/screenshot',
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PAGEBOLT_API_KEY}`,
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(payload)
}
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let data = Buffer.alloc(0);
res.on('data', (chunk) => {
data = Buffer.concat([data, chunk]);
});
res.on('end', () => {
if (res.statusCode === 200) {
fs.writeFileSync('admin-dashboard.png', data);
console.log('✓ Admin dashboard screenshot saved');
resolve(data);
} else {
reject(new Error(`API error ${res.statusCode}`));
}
});
});
req.on('error', reject);
req.write(payload);
req.end();
});
}
screenshotProtectedAPI().catch(console.error);
Multiple Cookies Example
If your app uses multiple cookies:
const payload = {
url: 'https://example.com/dashboard',
format: 'png',
cookies: [
{
name: 'session_id',
value: 'abc123xyz',
domain: 'example.com'
},
{
name: 'user_preferences',
value: 'theme=dark&lang=en',
domain: 'example.com'
},
{
name: '_ga',
value: 'GA1.2.1234567890.1234567890',
domain: 'example.com'
}
]
};
Extracting Cookies from Your Browser
Chrome DevTools
- Open your app in Chrome
- Open DevTools:
F12→ Application tab - Left sidebar → Cookies → select your domain
- Copy cookie names and values
Programmatic Extraction
// Node.js: Extract cookies from Puppeteer session
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com/login');
// (perform login steps)
const cookies = await page.cookies();
console.log(JSON.stringify(cookies, null, 2));
// Output:
// [
// {
// "name": "session_id",
// "value": "abc123xyz",
// "domain": "example.com",
// "path": "/",
// "httpOnly": true
// }
// ]
Production: Store Auth Tokens in Environment Variables
Never hardcode tokens. Use environment variables:
# .env
PAGEBOLT_API_KEY=YOUR_API_KEY
AUTH_SESSION_COOKIE=session_id=abc123xyz
AUTH_BEARER_TOKEN=eyJhbGciOiJIUzI1NiI...
// Use in code
const sessionCookie = process.env.AUTH_SESSION_COOKIE;
const bearerToken = process.env.AUTH_BEARER_TOKEN;
Handle Token Expiration
Tokens expire. Handle this gracefully:
async function screenshotWithAuthRefresh(url, getAuthToken) {
let attempts = 0;
const maxAttempts = 2;
while (attempts < maxAttempts) {
try {
const authToken = await getAuthToken();
const payload = {
url: url,
format: 'png',
headers: {
'Authorization': `Bearer ${authToken}`
}
};
const response = await fetch('https://api.pagebolt.dev/v1/screenshot', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PAGEBOLT_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
if (response.status === 401) {
console.log('Auth token expired, refreshing...');
attempts++;
continue; // Retry with new token
}
if (response.ok) {
return await response.arrayBuffer();
} else {
throw new Error(`API error ${response.status}`);
}
} catch (error) {
if (attempts < maxAttempts - 1) {
attempts++;
} else {
throw error;
}
}
}
}
Real-World Use Cases
Monitoring Dashboard Screenshots (Daily)
// monitor-dashboard.js
const cron = require('node-cron');
// Run every day at 9 AM
cron.schedule('0 9 * * *', async () => {
const token = await getLatestSessionToken(); // Your auth logic
const payload = {
url: 'https://example.com/dashboard',
format: 'png',
headers: {
'Authorization': `Bearer ${token}`
}
};
const screenshot = await takeScreenshot(payload);
await saveToS3(screenshot, `dashboards/${new Date().toISOString()}.png`);
});
Admin Panel Alerts
// admin-panel-alert.js
async function checkAdminPanel() {
const token = await getAdminToken();
const screenshot = await takeScreenshot({
url: 'https://internal.example.com/admin',
format: 'png',
headers: {
'Authorization': `Bearer ${token}`
}
});
// Compare against baseline
const diff = await compareImages(screenshot, baselineScreenshot);
if (diff > threshold) {
await sendAlert('Admin panel changed unexpectedly');
}
}
Security Best Practices
- Never log tokens — Don't print auth headers to console in production
-
Use environment variables — Store tokens in
.envor secret management (AWS Secrets Manager, etc.) - Rotate tokens regularly — Don't use the same token forever
- Use short-lived tokens — Prefer JWTs with expiration over long-lived session cookies
- HTTPS only — Always use HTTPS when passing auth data
- Validate responses — Check status codes; don't blindly assume success
Key Takeaways
-
Pass cookies via the API —
cookiesparameter accepts name/value pairs -
Use Bearer tokens for APIs — Pass in
headers.Authorizationheader - Support both auth methods — Cookies for web sessions, tokens for APIs
- Handle expiration — Refresh tokens and retry on 401
- Secure your tokens — Use environment variables, rotate regularly
Next step: Get your free API key at pagebolt.dev. 100 requests/month, no credit card required.
Try it free: https://pagebolt.dev/pricing
Top comments (0)