严格的 CSP:如何在 next.js 中为样式组件设置随机数?

The*_*eoG 6 javascript reactjs next.js

所以,我试图用 nounce 属性填充我的 next.js 项目中的样式组件,但没有成功。正在设置 CSP 的 style-src,但由于未在样式中设置 nounce,因此会引发错误。我还需要做什么才能完成这项工作?

到目前为止,我所拥有的如下:

服务器.js

server.use((req, res, next) => {
  // nonce should be base64 encoded
  res.locals.styleNonce = Buffer.from(uuidv4()).toString('base64')
  next()
});

  server.use('*', (req, res, next) => {
    global.__webpack_nonce__ = res.locals.styleNonce;
    next()
  });

  server.use(helmet.contentSecurityPolicy({
      directives: {
          styleSrc: ["'self'", (req, res) => `'nonce-${res.locals.styleNonce}'`],
      }
  }));
Run Code Online (Sandbox Code Playgroud)

_document.js

export default class MyDocument extends Document {
  static getInitialProps({ renderPage }) {
    const sheet = new ServerStyleSheet();
    const page = renderPage(App => props => sheet.collectStyles(<App {...props} />));
    const styleTags = sheet.getStyleElement();
    return { ...page, styleTags };
  }
  render() {
    return (
      <Html lang="en">
        <Head>{this.props.styleTags}</Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

dim*_*sus 0

在 中document.js,虽然必须通过 props 提供随机数,但 Next.js 具有将随机数应用于 和 中所有加载的脚本/链接的功能head-body如果提供了随机数。

我面临的唯一主要问题是在next/head组件级别有条件加载脚本,例如在接受cookie之后......事情变得更加复杂。

  render() {
    const { styleTags, language, nonce } = this.props;

    return (
      <html lang={language}>
        <Head {...{ nonce }}>
          {styleTags}
        </Head>
        <body>
          <Main />
          <NextScript {...{ nonce }} />
        </body>
      </html>
    );
  }
Run Code Online (Sandbox Code Playgroud)