微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用Webpack,内容安全策略以及对自己的服务器和外部站点的提取/ ajax调用?

如何解决如何使用Webpack,内容安全策略以及对自己的服务器和外部站点的提取/ ajax调用?

我在entry.js文件添加了访存调用

fetch('https://ipinfo.io/json')
  .then(response => response.json())
  .then(data => console.log(data));

我的webpack构建很好,直到我添加了它,然后我开始遇到有关内容安全政策的错误

以前,我没有定义任何内容安全策略。

我已经尝试了几种解决错误方法(请参阅文章结尾),最新方法是将其添加到index.html文件的开头部分:

<Meta http-equiv="Content-Security-Policy" content="script-src 'self'; connect-src https://ipinfo.io/json">

现在,我在Chrome开发者工具控制台中遇到了这些错误,它们似乎相互矛盾:

错误#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,但是发生第一个错误是因为它已明确设置

错误#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的其他方法之一:

我将此添加到了entry.js

__webpack_nonce__ = 'something-tricky';

这是索引文件<head>部分:

<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组合时,我注意到它开始破坏很多东西,例如:

  • index.html中的脚本标签链接到Google字体等
  • css样式生成并包含在bundle.js中

因此,我意识到有必要完全正确地使用CSP,否则它将根本无法正常工作。

修改

我最后的尝试是这样

<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"); 

最后一个错误很奇怪,因为它似乎是忽略我在srcipt-src指令中特别“列入白名单”的域。

解决方法

好吧,好吧,我在Chrome开发人员工具的Network标签中查看了其他请求,并看到Response Headers标签中应用了相当丰富的CSP指令集,但我没有设置他们,所以我想知道它们来自哪里。

我碰到了this answer,其中提到可以使用helmet in node设置它们

因此在我的节点应用程序中,我替换了:

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的请求正在运行:

$.get("https://ipinfo.io/json",function(response) {
  console.log(response);
},"jsonp"); 

请注意,我必须在unsafe-inline上添加StyleSrc,否则使用webpack导入并捆绑到bundle.js的CSS将无法正常工作。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。