如何使用Webpack,内容安全策略以及对自己的服务器和外部站点的提取/ ajax调用? [英] How to use webpack, content security policy and fetch/ajax calls to own server and external sites?
问题描述
我在 entry.js
文件中添加了访存调用:
I added a fetch call in my entry.js
file:
fetch('https://ipinfo.io/json')
.then(response => response.json())
.then(data => console.log(data));
我的webpack构建很好,直到我添加了它,然后我才开始遇到有关内容安全策略的错误。
My webpack build was fine until I added that, then i started getting errors regarding Content Security Policy.
以前,我没有定义任何内容安全策略。
Previously, I didn't have any content security policy defined.
我已经尝试了几种方法来解决错误(请参见文章末尾),最新添加的是这是index.html文件的开头部分:
I've tried several approaches to resolve errors (see end of post), the latest was adding this to head section of index.html file:
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; connect-src https://ipinfo.io/json">
现在,我在Chrome开发者工具控制台中遇到了这些错误,它们似乎相互矛盾:
Now I am getting these errors in Chrome developer tools console, which seem to contradict themselves:
错误#1-与jquery ajax获取对我自己的api的请求
bundle.js:25 Refused to connect to 'http://localhost:3000/api/v1/resource?parameter=false&_=1598715905517' because it violates the following Content Security Policy directive: "connect-src https://ipinfo.io/json".
错误#2-与提取对外部网站的调用有关
bundle.js:1 Refused to connect to 'https://ipinfo.io/json' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback.
注意:第二个错误表明 connect-src
不是显式设置,但是发生第一个错误是因为显式设置了 。
Note: This second error says that connect-src
is not explicitly set, however the first error occurs because it is explicitly set.
错误#3-与提取外部网站调用有关
bundle.js:1 Refused to connect to 'https://ipinfo.io/json' because it violates the document's Content Security Policy.
错误#4-与提取对外部网站的调用有关
bundle.js:1
Uncaught (in promise) TypeError: Failed to fetch
at HTMLDocument.<anonymous> (bundle.js:1)
at u (bundle.js:25)
at l (bundle.js:25)
其他方法
作为参考,这是我尝试使用 nonce <的其他方法之一。 / code>:
For reference, here is one of the other approaches I tried using a nonce
:
我将此添加到 entry.js
:
__webpack_nonce__ = 'something-tricky';
这就是索引的< head>
部分文件:
And this to the <head>
section of the index file:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'nonce-something-tricky';
结果是它不会加载 bundle.js
:
Refused to load the script 'http://localhost:3000/js/bundle.js' because it violates the following Content Security Policy directive: "script-src 'nonce-something-tricky'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
此方法基于:
https://webpack.js.org/guides/csp
https://stackoverflow.com/a/42924000
其他上下文
当我开始尝试< head>
部分中的各种CSP组合时,我注意到它开始破坏很多东西,例如:
As i started trying all sorts of CSP combinations in the <head>
section, I noticed it started breaking lots of things like:
- 脚本标签将
index.html
中的链接链接到Google字体等 - css样式生成并包含在bundle.js中
- script tag links in
index.html
to google fonts etc - css styles generated and included in bundle.js
所以我知道需要完全正确地使用CSP,否则就不会
So i'm aware of the need to get CSP completely right, or it won't work at all.
编辑
我最后一次尝试是:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://ipinfo.io; style-src 'self' fonts.googleapis.com 'unsafe-inline'; font-src 'self' fonts.gstatic.com">
我收到此错误:
bundle.js:25 Refused to load the script 'https://ipinfo.io/json?callback=jQuery35106635073412967416_1598793439782&_=1598793439783' because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
此代码在 entry.js
文件中时:
$.get("https://ipinfo.io/json", function(response) {
console.log(response);
}, "jsonp");
最后一个错误很奇怪,因为它似乎忽略了我专门指定的域'
That last error is weird, because it seems to be ignoring the domain that I specifically 'whitelisted' in the srcipt-src
directive.
推荐答案
好吧,好吧,在 srcipt-src
指令中将其列入白名单。我查看了Chrome开发人员工具中的网络
标签以查看其他请求,并看到在响应标题中应用了一套相当丰富的CSP指令
标签,但我没有设置它们,所以我想知道它们的来源。
Ok, well i looked at the Network
tab in Chrome developer tools for other requests and saw a rather rich set of CSP directives were being applied in the Response Headers
tab, but i hadn't set them, so I wondered where they were coming from.
我遇到了这个答案,其中提到可以使用节点中的头盔进行设置
I came across this answer, which mentioned that they could be set using helmet in node
因此在我的节点应用程序中,我替换了:
So in my node app, I replaced:
app.use(helmet());
具有:
app.use(
helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "https://ipinfo.io"],
styleSrc: ["'self'", "fonts.googleapis.com", "'unsafe-inline'"],
fontSrc: ["'self'", "fonts.gstatic.com"]
}
},
})
);
现在,来自 entry.js
的请求正在运行:
and now this request from entry.js
is working:
$.get("https://ipinfo.io/json", function(response) {
console.log(response);
}, "jsonp");
请注意,我必须在< unsafe-inline
中添加 StyleSrc
,否则使用webpack导入并捆绑到 bundle.js
的CSS无效。
Note, I had to add unsafe-inline
to the StyleSrc
or else the CSS that was imported and bundled into bundle.js
using webpack wouldn't work.
这篇关于如何使用Webpack,内容安全策略以及对自己的服务器和外部站点的提取/ ajax调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!