nginx 跨域 没有cookie_来看一波浏览器跨域?

刚迈进前端大门的时候,就听说过一句话,浏览器不允许跨域是为了安全,所以,为啥允许跨域就会不安全?

自由开放是人们不变的追求,Web 世界也是这样,这很符合 Web 的理念,但是,如果是绝对自由的,任何资源都可以接入,可以下载其他站点的可执行脚本,让我们发散一下,这会发生什么现象?

这一天,我登录了我的银行页面,这时候,如果下面有一个恶意站点的小广告,我手一贱就那么点进去了,然后愉快的在银行页面输入了我的账号密码,注意,现在浏览器没有什么安全策略,绝对的自由,那么,这个恶意站点就可以修改银行站点的 DOM、样式等信息,并且可以植入 JS 脚本,劫持到了我的用户名和密码,读取银行站点的 cookie、indexDB 等数据,然后把这些东西都发送到了自己的服务器,这样,这个恶意网站就可以在我本人并不知情的情况下伪造一些转账请求。我的天,这不是要命?

所以,这种现象是万万不能允许存在的,如果浏览器没有安全策略,那我们的信息就相当于在操场上裸奔,毫无隐私可言,这样就引出了我们页面中最核心的安全策略:同源策略(Same-origin policy)

什么是同源策略?

三同:同协议、同域名、同端口

浏览器默认两个相同源之间是可以相互访问资源和 DOM 的,具体来说,同源策略主要体现在 DOM、web 数据和网络层面上。

DOM 层面

如果两个页面是同源关系,那么我们就可以在第二个页面中操作第一个页面,否则会报错

b7831c6d382d9da286968c6494a4a4b7.png

7dc1982a1724a705a51de5f676c540f9.png

接下来,就是见证奇迹的时刻了:

8cfd602313e26a80de848beb4b76a20c.png

第一个页面的 DOM 元素真的被我们"藏起来"了。

但是,如果我们两个页面是不同域的,就会报错

1d9b1c2eb8f982e661962a545ce033a7.png

b3218a7198a4ff40187a3e11ef3b9683.png

数据层面

同源策略限制了我们没有办法拿到非同源下面的 cokkie、IndexDB、localStorage 等数据

网络层面

XMLHttpRequest 在默认情况下,不允许访问跨域的资源。

简单点来说,就是同域下,你想怎么搞,就怎么搞,放飞自我,不受限制,但是想要在不同源之间瞎搞就只能使用点特殊手段了。兴奋的搓手手~

我们怎么解决跨域问题?

让我们看看有哪些手段能让我们打破跨域的带来的限制。

DOM 层面

在开发过程中,可能需要两个不同源页面的DOM 进行通信,所以浏览器引入了跨文档消息机制,可以通过 window.postMessage 的 JavaScript 的接口。

这里有几个点需要注意,postMessage 的语法是:

targetWindow.postMessage(message, targetOrigin, [transfer]);

第三个参数 targetOrigin 最好提供具体的 url 而不是 *,以防恶意的第三方窃取密码。如果不希望收到其他站点的信息,不要为 message 事件添加任何事件监听器,如果在迫不得已的情况下必须要接受来自其他站点的消息,那么请务必检验发送者的身份信息,这很重要。

第三方资源

第三方资源我们要解决的是给他的自由过了火,需要有所限制。

同源策略要让网页的所有资源都来自同一个源,这样所有资源必须部署在同一台服务器上,太不自由了,带来了太多限制,所以同源策略在页面引用开了个后门,可以对任意文件进行引用。

一开始浏览器都是支持外部引用资源文件的,不过这也带来了很多问题,容易受到 XSS 攻击。这时候。浏览器又引入了CSP(内容安全策略),CSP 的核心思想是让服务器来决定浏览器能够加载哪些资源,让服务器决定浏览器能否执行内联的 JS 代码。说白了,就是白名单制度,这样,攻击者就算是发现了漏洞,也没有办法注入脚本。

可以通过 HTTP 头部信息的 Content-Security-Policy 字段来启用 CSP,另一种方式是通过页面的 标签

网络层面

经历过面试的小伙伴都知道,有一个经典的面试题:请问你怎么解决跨域?

跨域资源共享(CORS)可以进行跨域访问控制,需要浏览器和服务器同时支持,是为了跨域数据传输更加安全。

浏览器将 CORS 分为两类请求:简单请求、非简单请求。

只要同时满足以下两大条件就属于简单请求:

  1. 请求方法是以下三种之一:

  • HEAD

  • GET

  • POST

2. HTTP 头部信息不超出以下几种字段

    • Accept

    • Accept-Language

    • Content-Language

    • Last-Event-ID

    • Content-Type: 只限于三个值 application/x-www-form-urlencoded、multipart/form-data、text/plain

    • DPR

    • Downlink

    • Save-Data

    • Viewport-Width

    • Width

非简单请求时那种对服务器有特殊要求的请求,像是 PUT 或者 DELETE,或者 Content-Type 字段的类型是 application/json。

浏览器会先发送一个预检请求,请求方法是 OPTIONS,表示这个请求时用来询问的,头部信息里面,关键字是 Origin,表示来自哪个源,除了 Origin 以外,还包括 Access-Control-Request-Method 和 Access-Control-Request-Header。一旦服务器通过了预检请求,以后每次浏览器正常的 CORS 请求就像是简单请求一样了,与 JSONP 相比,CORS 更加强大, JSONP 只支持 GET 请求,而 CORS 支持所有类型的 HTTP 请求, JSONP 的优势是支持老式浏览器,老式浏览器不支持 CORS 的话可以使用 JSONP。不过,如果你还需要兼容到这么老版本了浏览器,表示默默的心疼你。

服务端一般需要设置 Access-Control-Allow-Origin: * 等字段来允许浏览器跨域,如果浏览器需要发送 cookie 信息,在前端项目中需要设置 XMLHttpRequest 的 withCredentials 属性为 true。

除了 CORS 以外,使用 nginx 反向代理也是我们常见解决跨域的方式,这种方式的的原理跟 CORS 跨域原理一样,通过配置文件设置响应头 Access-Control-Allow-Origin...等字段。通过 nginx 配置一个代理服务器域名与 domain1 相同,端口不同做跳板机,反向代理访问 domain2 接口,并且可以顺便更改 cookie 中的 domain 信息,方便当前域 cookie 写入,实现跨域访问。

#proxy服务器
server {
listen 8081;
server_name www.domain1.com;

location / {
proxy_pass http://www.domain2.com:8080; #反向代理
proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名
index index.html index.htm;

# 当用webpack-dev-server等中间件代理接口访问nignx时,此时无浏览器参与,故没有同源限制,下面的跨域配置可不启用
add_header Access-Control-Allow-Origin http://www.domain1.com; #当前端只跨域不带cookie时,可为*
add_header Access-Control-Allow-Credentials true;
}
}

总结

首先我们讲解了一下浏览器最核心的安全策略—同源策略(三同:同协议、同域名、同端口), 同源策略确实能够让我们的页面更加安全,但是安全性与便利性是相对的,如果让不同源之间绝对隔离,这会让 Web 项目变得难以开发和使用,浏览器不得不出让在此策略下的一些安全性,为了我们能够在像是同源一样胡作非为,提供了 跨资源共享策略和跨文档信息机制。但是如果页面足够灵活,又容易引发安全问题,比如 XSS 攻击,为了防止第三方资源引起的 XSS 攻击问题,浏览器采用了 CSP 来限制其自由度。

参考链接

https://juejin.im/post/5d1ecb96f265da1b6d404433#heading-12

https://www.ruanyifeng.com/blog/2016/04/cors.html

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP

http://www.ruanyifeng.com/blog/2016/09/csp.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Nginx是一种Web服务器和反向代理服务器,在Web应用程序中使用广泛。Nginx的主要特点是高性能、高并发、低内存占用以及模块化。在Web应用程序的开发中,经常用到cookie技术来存储和传递客户端的状态信息。但是,由于浏览器的特殊限制,cookie不能传递。如果需要在不同的名之间传递cookie,就需要采用其他的方法。 Nginx提供了一种传递cookie的解决方案,称为Nginx cookie。这种方法基于HTTP头部中的Set-Cookie和Cookie字段来实现传递cookie。具体实现方法如下: 1. 在Nginx的配置文件中,添加以下代码: http { ... upstream myapp { server 127.0.0.1:8080; } server { ... location / { proxy_pass http://myapp; proxy_set_header Cookie $http_cookie; proxy_cookie_path / /; } } } 2. 该配置中,upstream用于定义后端服务器的地址和端口号。server用于定义监听的地址和端口号,location用于定义请求的路径。 3. 在location中,proxy_pass用于转发请求到后端服务器,proxy_set_header用于设置请求头部中的Cookie字段,proxy_cookie_path用于设置Cookie的存储路径。 4. 当浏览器发送请求到Nginx服务器时,Nginx会将请求转发到后端服务器。在转发的过程中,Nginx会将请求头中的Cookie字段传递给后端服务器。后端服务器接收到请求后,将生成一个新的Cookie,并将该Cookie存储在服务器端。然后将该Cookie作为响应头部中的Set-Cookie字段返回给Nginx。 5. 当Nginx收到响应后,会将Set-Cookie字段中的值传递给浏览器浏览器接收到响应后,会将该Cookie存储在本地。当浏览器再次向Nginx发送请求时,Nginx会将存储在本地的Cookie传递给后端服务器。这样,就实现了Nginx cookie传递的目的。 总结来说,Nginx cookie实现的原理就是在Nginx服务器与后端服务器之间进行数据传递,并将cookie存储在服务器端,浏览器则只存储一份。这种方法可以避免cookie被恶意注入或窃取,提升了网站的安全性。同时,这种方法也可以提高网站的访问效率,减少因cookie传递而造成的性能损耗。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值