如何将published过滤器设为safeFilter?Apostrophe-Headless预览未发布内容问题
1. Can the published filter be set as a safeFilter?
First, let’s clarify: In Apostrophe, a "safe filter" refers to a filter that’s allowed in public API requests (no admin authentication required). The built-in published filter is already a safe filter by default, but it restricts unauthenticated users to only seeing published content (published=true).
If you want to let public requests (like your staging server’s calls) access unpublished content by using published=any, you’ll need to override the filter’s behavior for your staging environment. Here’s how:
- In your Apostrophe project, modify the
lib/modules/apostrophe-pieces/index.jsfile (or the specific piece type you’re working with, e.g.,apostrophe-pagesfor pages):
module.exports = { filters: { published: { choices: [ { label: 'Published', value: true }, { label: 'Unpublished', value: false }, { label: 'Any', value: 'any' } ], def: (req) => { // Allow all content in staging without authentication if (process.env.NODE_ENV === 'staging') { return 'any'; } // Default: only published content for public users, all for admins return req.user ? 'any' : true; }, safe: true // Confirm it’s accessible to public requests } } };
This setup will automatically return all content (published and unpublished) in staging, or let you explicitly use published=any in API calls without needing to log in.
2. Accessing Unpublished Content in Staging via Server-Side Next.js Calls
The core issue here is that unauthenticated server-side calls to Apostrophe’s API only get published content. Here are three solid fixes:
Option 1: Environment-Based Filter Override (As Above)
The solution from question 1 is the simplest—override the published filter to default to any in staging. This means your server-side calls don’t need any extra authentication to fetch all content.
Option 2: Use an API Key for Server-Side Authentication
If you want to keep the filter restrictive but let your Next.js server authenticate:
- Add an API key to your Apostrophe
app.js:
module.exports = { modules: { 'apostrophe-api': { apiKeys: [process.env.APOSTROPHE_API_KEY] } } };
- Set the
APOSTROPHE_API_KEYenvironment variable in both your Apostrophe and Next.js staging servers. - Include the key in your Next.js server-side request headers:
const res = await fetch(`${process.env.APOSTROPHE_API_URL}/api/v1/pieces/your-piece-type`, { headers: { 'Authorization': `Bearer ${process.env.APOSTROPHE_API_KEY}` }, // Add parameters like published=any if needed });
This authenticates your server calls, giving them the same access as a logged-in admin.
Option 3: Create a Staging-Specific API Endpoint
For more control, build a custom endpoint in Apostrophe that returns all content exclusively for staging:
- Create a module like
apostrophe-staging-api:
module.exports = { construct: function(self, options) { self.route('get', '/staging-content', async function(req, res) { // Block access outside staging if (process.env.NODE_ENV !== 'staging') { return res.status(403).send('Forbidden'); } // Fetch all content without published restrictions const pieces = await self.apos.pieces.find(req, 'your-piece-type', {}).toArray(); res.send(pieces); }); } };
- Call this endpoint from your Next.js staging server to get all content directly.
内容的提问来源于stack exchange,提问作者Blaine O'Brien




