React + Electron, content security policy блокирует fetch запросы из компонента React к сторонним api
Помогите пожалуйста исправить проблему с Content security policy.
Проблема заключается в следующем:
При помощи Electron Forge внедрил свое ReactJS приложение в ElectronJS, но возникла проблема с политикой безопасности, а конкретно - Electron не дает выполнять fetch запросы на сторонний API (проблема еще усугубляется тем, что API домен без SSL, простой http://).
Fetch запрос выполняется из компонента App при первом рендере (ComponentDidMount), но он сразу же блокируется.
Пытался работать с CSP и через manifest.json, и через главный файл Electron, и что то там делал с другими конфигурациями тегов, но все тщетно.
Отключил web безопасность в электрон, разрешил подключение к протоколам http/https (webPreferences: {webSecurity: false, allowRunningInsecureContent: true}) тоже никак не влияет на ситуацию.
Метод который давал хоть какую то реакцию это - через: <meta http-equiv="content-security-policy" ...>,
прописывал различные конфигурации.
При добавлении домена с API в connect-src ошибка с доменом API вроде как пропадает, но появляется при этом та же проблема что и с API, но только с http://localhost:3000, если добавляю http://localhost:3000 к connect-src через пробел, все возвращается к исходному результату и в ошибке написано, что connect-src явно не определен и применен default-src 'self' (хоть он и с другим значением).
Проблема с http(ws)://localhost:3000 решается вот этой конфигурацией:
<meta http-equiv="Content-Security-Policy"
content="default-src 'unsafe-eval';
script-src-elem http:;
connect-src ws: http: http://data.fixer.io/;
style-src 'self' 'unsafe-inline'">
Но никак не решает проблему с блокировкой API (http://data.fixer.io/) даже добавив его в список connect-src.
В консоли вот это:
Пишет что connect-src явно не указан, хотя он указан и работает для http(ws)://localhost:3000. Либо я чего не понимаю...
Перечитал тонну различной информации на англоязычных сайтах, но не нашел ничего рабочего, в рунете тоже ничего.
Вот ссылка на сам проект в GitHub ссылка на проект
P.S. Само приложение ReactJS без Electron работает корректно, все fetch запросы отрабатывают так как запланировано.
P.P.S. Прошу сильно не ругать, я новичек во всем этом, и это мое первое учебное приложение в связке React + Electron. Спасибо за понимание!
Заранее благодарен за любую информацию, которая даст хотя бы правильное направление для поиска решения проблемы.
Ответы (1 шт):
connect-srcявно не определен и примененdefault-src 'self'(хоть он и с другим значением).
У вас уже публикуется Content Security Policy (CSP), поэтому добавленный вами метатег не работает. Он просто добавляет вторую CSP, но первая продолжает всё блокировать. Это как раз и видно видно по блокирующим правилам: default-src 'self' 'unsafe-inline' data: - они от первой CSP, а не из вашего мета тега.
Поэтому вам надо найти где публикуется первая CSP и добавить источник http://data.fixer.io в неё.
В режиме Prod CSP в Электрон публикуется только посредством метатега.
В режиме Dev (а судя по http(ws)://localhost:3000 в находитесь в режиме Разработки), CSP также может быть опубликована посредством HTTP-заголовка. Проверьте, не издаёте ли вы CSP в HTTP-заголовке (оно на Eng, но там важна только картинка).
Проверьте наличие в коде вашего Приложения участка:
session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
callback({ responseHeaders: Object.assign({
...details.responseHeaders,
"Content-Security-Policy": [ "default-src 'self' 'unsafe-inline' data:" ]
}, details.responseHeaders)});
});
он может издавать заголовок CSP в режиме Dev. Также CSP заголовок могут издавать плагины electron-forge и electron-forge/plugin-webpack - у них есть настройка CSP для режима разработки (Dev).
И проверьте HTML код вашего приложения в браузере на наличие второго мета тега <meta http-equiv="Content-Security-Policy", поскольку плагины могут публиковать его и посредством мета тега тоже. Тогда в HTML коде будет 2 мета тега: один ваш, второй от плагина.
Замечание. Описываемое вами поведение при добавлении http(ws)://localhost:3000 - это ложный след, localhost обычно покрывается токеном 'self', который у вас есть в обеих CSP.
ws://localhost:3000 нужен только если используются вебсокеты, для обычных fetch-запросов достаточно http://localhost:3000.