如何使用Webpack,内容安全策略以及对自己的服务器和外部站点的提取/ ajax调用? [英] How to use webpack, content security policy and fetch/ajax calls to own server and external sites?

查看:233
本文介绍了如何使用Webpack,内容安全策略以及对自己的服务器和外部站点的提取/ ajax调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆