Одним из решений является передача всей генерации контента и кэширования веб-приложению (в вашем случае Node), а генерация одноразовых номеров CSP - интерфейсному веб-серверу (например, Nginx).Я реализовал это с Django, который выполняет кэширование страниц с ETag
, выполняет всю логику заголовка Vary
и т. Д., И HTML-код, который он генерирует, содержит такой статический заполнитель одноразового номера CSP:
< script nonce="+++CSP_NONDE+++"> ... </script>
Этот заполнитель тогдазаполненный Nginx с использованием ngx_http_subs_filter_module
:
sub_filter_once off;
sub_filter +++CSP_NONCE+++ $ssl_session_id;
add_header Content-Security-Policy "script-src 'nonce-$ssl_session_id'";
Я видел решения, использующие дополнительный модуль Nginx для генерации действительно уникального случайного одноразового номера для каждого запроса, но я считаю, что это излишнее, и я просто использую TLSидентификатор сеанса, который уникален для каждого подключающегося клиента и может кэшироваться в течение некоторого времени (например, 10 минут) в зависимости от конфигурации Nginx.
Просто убедитесь, что веб-приложение возвращает несжатый HTML, поскольку Nginx не сможетсделать подстановку строк.