You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将published过滤器设为safeFilter?Apostrophe-Headless预览未发布内容问题

Answers to Your Apostrophe-Headless Questions

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.js file (or the specific piece type you’re working with, e.g., apostrophe-pages for 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:

  1. Add an API key to your Apostrophe app.js:
module.exports = {
  modules: {
    'apostrophe-api': {
      apiKeys: [process.env.APOSTROPHE_API_KEY]
    }
  }
};
  1. Set the APOSTROPHE_API_KEY environment variable in both your Apostrophe and Next.js staging servers.
  2. 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:

  1. 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);
    });
  }
};
  1. Call this endpoint from your Next.js staging server to get all content directly.

内容的提问来源于stack exchange,提问作者Blaine O'Brien

火山引擎 最新活动