在项目中有遇到“跨域”,so要对跨域有个清楚认识,并对安全知识进行简单总结
注:
一、跨域
简述:
跨域:是指a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。注意:跨域限制访问,其实是浏览器的限制。
跨域问题:
1. jsonp可以解决
2. cors设置Access-Control-Allow-Origin头
3. nginx解决,搭建一个中转nginx服务器,用于转发请求
1、为什么会出现跨域问题
出于浏览器的同源策略限制。
同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。
同源策略限制了从同一个源加载的文档或脚本与另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。
所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)
2、什么是跨域
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
3、非同源限制
【1】无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB
【2】无法接触非同源网页的 DOM
【3】无法向非同源地址发送 AJAX 请求
4、跨域解决方法
【1】JSONP
JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。
核心思想:网页通过添加一个<script>元素,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。
<script src="http://test.com/data.php?callback=dosomething"></script>
// 向服务器test.com发出请求,该请求的查询字符串有一个callback参数,用来指定回调函数的名字
// 处理服务器返回回调函数的数据
<script type="text/javascript">
function dosomething(data){
//处理获得的数据
}
</script>
【2】CORS 是处理跨域问题的标准做法
原理:CORS是一个W3C标准,全称是"跨域资源共享"。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。它为Web服务器定义了一种方式,允许网页从不同的域访问其资源.
CORS系统定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。 它是一个妥协,有更大的灵活性,但比起简单地允许所有这些的要求来说更加安全。
实现方法:
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
浏览器将CORS请求分成两类:简单请求和非简单请求。
1、简单请求:只要同时满足以下两大条件
(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
简单请求:只服务端设置, 在response中加header:Access-Control-Allow-Origin即可,若要带cookie请求:前后端都需要设置。
response.setHeader("Access-Control-Allow-Origin", *);
注意:*时cookie不会在http请求中带上
如果需要http请求中带上cookie,需要前后端都设置credentials,且后端设置指定的origin
response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
2.非简单请求
非简单请求的cors请求,会在正式通信之前,发出一次预检测请求,返回码是204,预检测通过才会真正发出请求,这才返回200。这里通过前端发请求的时候增加一个额外的headers来触发非简单请求。
// 如果需要http请求中带上cookie,需要前后端都设置credentials,且后端设置指定的origin
response.setHeader('Access-Control-Allow-Origin', 'http://localhost:9099')
response.setHeader('Access-Control-Allow-Credentials', true)
// 非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)
// 这种情况下除了设置origin,
// 还需要设置Access-Control-Request-Method以及Access-Control-Request-Headers
response.setHeader('Access-Control-Request-Method', 'PUT,POST,GET,DELETE,OPTIONS')
response.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, t')
【3】nginx反向代理
想一下,如果我们请求的时候还是用前端的域名,然后有个东西帮我们把这个请求转发到真正的后端域名上,不就避免跨域了吗?这时候,Nginx出场了。
实现原理类似于中间件代理,需要你搭建一个中转nginx服务器,用于转发请求。
使用nginx反向代理实现跨域,是最简单的跨域方式。只需要修改nginx的配置即可解决跨域问题,支持所有浏览器,支持session,不需要修改任何代码,并且不会影响服务器性能。
实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。
Nginx转发的方式似乎很方便!但这种使用也是看场景的,如果后端接口是一个公共的API,比如一些公共服务获取天气什么的,前端调用的时候总不能让运维去配置一下Nginx,如果兼容性没问题(IE 10或者以上),CROS才是更通用的做法吧。
二、加密算法
1、特征:
-
可逆加密为:1.对称加密、2.非对称加密
-
不可逆加密:摘要:MD5、SHA1。
-
1、AES对称密钥:每次生成都是随机的,AES256
-
2、RSA非对称密钥:RSA 2048 长度不到128,强度没有AES256 好
-
3、摘要:保证数据的完整性 MD5 长度需要除2
-
4、数字签名:SHA256withRSA2048 前面是摘要后面是加密,先摘要再加密
2、数字签名总结
目的:我加密让别人来验,所以是私钥加签,公钥验签
数字签名,简单来说就是通过提供可鉴别的数字信息验证自身身份的一种方式。一套数字签名通常定义两种互补的运算,一个用于签名,另一个用于验证。即:加签、验签
分别由发送者持有能够代表自己身份的私钥 (私钥不可泄露),由接受者持有与私钥对应的公钥 ,能够在接受到来自发送者信息时用于验证其身份。
注意:正常加密过程:公钥加密,私钥解密。
1、签名****最根本用途是要能够唯一证明发送方的身份,防止中间人攻击,CSRF跨域身份伪造
2、基于这一点在诸如设备认证、用户认证、第三方认证等认证体系中都会使用 签名算法
3、应用
加密cookie:A+B+C
1、拼接 byte[ ] content = A+B+C, 通过SHA256签名,得到2位验证码captcha(第2、4位)
2、对 byte[ ] encrypt = A+B 进行AES128加密
3、组合 captcha+ encrypt,再转为string,得到一个加密串result
4、最后通过 result:c 组合成结果
解密cookie
1、冒号分割,获取前半段
2、经行base64解密,得到验证码和加密串 captcha+ encrypt
3、用AES128对加密串encrypt 进行解密,得到加密详情 A+B
4、对详情 A+B+C 通过SHA256签名,得到2位验证码captcha2
5、与第2步的验证码 captcha 进行比较,相同,说明cookie正确,即返回详情
4、为什么要使用Base64加密呢?
Base64编码的作用:由于某些系统中只能使用ASCII字符。Base64就是用来将非ASCII字符的数据转换成ASCII字符的一种方法。它使用下面表中所使用的字符与编码。
而且base64特别适合在http,mime协议下快速传输数据。
base64其实不是安全领域下的加密解密算法。虽然有时候经常看到所谓的base64加密解密。其实base64只能算是一个编码算法,对数据内容进行编码来适合传输。虽然base64编码过后原文也变成不能看到的字符格式,但是这种方式很初级,很简单。
二、Web安全
1.前端安全
- XSS 漏洞
- CSRF 漏洞
2.后端安全
-
SQL 注入漏洞
三、补充
1、是否每次请求都会在ssl中验证密钥? www.zhihu.com/question/67…
2、在https验证过程中用到对称加密和非对称加密,具体是什么算法:
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 服务器发回给客户端的Cipher