1

我正在使用 express 提供一个反应应用程序构建。

const root = path.join(__dirname, 'build/');
app.use(express.static(root));
app.use((req, res, next) => {
  if (req.method === 'GET' && req.accepts('html') && !req.is('json') && !req.path.includes('.')) {
    res.sendFile('index.html', { root });
  } else next();
});

一切都按预期工作。但是,一旦我将helmet(不是 react-helmet)添加到 express 应用程序,我就会遇到问题(样式和脚本未加载)。在搜索了几个资源之后,我能够想出一个解决方案来使它工作。下面的代码显示了我为加载样式和脚本所做的修复。

app.use(helmet());
app.use(helmet.contentSecurityPolicy({
  defaultSrc: [
    '\'self\'',
    'https://api.domain.tld/*',
    'https://domain.tld',
  ],
  styleSrc: [
    '\'self\'',
    '\'unsafe-inline\'',
    'https://*.googleapis.com',
    'https://api.domain.tld/*',
    'https://domain.tld',
  ],
  scriptSrc: [
    '\'self\'',
    '\'unsafe-inline\'',
    'https://api.domain.tld/*',
    'https://domain.tld',
  ],
  contentSrc: [
    '\'self\'',
    '\'unsafe-inline\'',
    'https://api.domain.tld/*',
    'https://domain.tld',
  ],
}));

此外,我还包括INLINE_RUNTIME_CHUNK=false.env file.

我目前遇到的问题是我正在进行的 API 调用api.domain.tld不起作用。它被阻止,并且在 Firefox 上显示以下错误。

内容安全策略:页面设置阻止在https://api.domain.tld/endpoint(“default-src”)加载资源。

Chrome 显示以下错误。

拒绝连接到“https://api.domain.tld/endpoint”,因为它违反了以下内容安全策略指令:“default-src 'self'”。请注意,'connect-src' 没有明确设置,因此 'default-src' 用作后备。

  • 请注意,react 应用程序已打开domain.tld且 API 已打开api.domain.tld

如果解决此问题,我该如何进行 API 调用?

4

2 回答 2

1

有2个问题:

  1. 修复语法错误:contentSrc:->connectSrc:

  2. CSP 规范不允许在路径部分使用 * (通配符),因此请修复 'https://api.domain.tld/*-> 'https://api.domain.tld/'。同样在路径部分中,您可以使用:

  • 文件夹名称:('https://api.domain.tld/real_path_here/'带有斜杠/) - 将允许指定文件夹和子目录中的任何子文件夹和任何文件。
  • 文件名:'https://api.domain.tld/endpoint''https://api.domain.tld/some_path/script.js'(不带斜杠/) - 仅允许指定的文件名。
于 2021-08-01T19:26:40.847 回答
0

根据文档,您应该在directives

app.use(helmet.contentSecurityPolicy({
  useDefaults: false, // you can change it to `true` if you want.
  directives:{
    defaultSrc: [
      '\'self\'',
      'https://api.domain.tld/',
      'https://domain.tld',
    ],
    styleSrc: [
      '\'self\'',
      '\'unsafe-inline\'',
      'https://*.googleapis.com',
      'https://api.domain.tld/',
      'https://domain.tld',
    ],
    'image-src': [
      '\'self\'',
      '\'unsafe-inline\'',
      'data:',
      'https://api.domain.tld/',
      'https://domain.tld',
    ],
    scriptSrc: [
      '\'self\'',
      '\'unsafe-inline\'',
      'https://api.domain.tld/*',
      'https://domain.tld',
    ],
    contentSrc: [
      '\'self\'',
      '\'unsafe-inline\'',
      'https://api.domain.tld/',
      'https://domain.tld',
    ],
  }
}));

更新

要修复图像未加载问题,请添加以下内容。

   imageSrc: [
      '\'self\'',
      '\'unsafe-inline\'',
      'data:',
      'https://api.domain.tld/',
      'https://domain.tld',
   ],
于 2021-08-01T18:25:47.040 回答