傻傻分不清之 Cookie、Session、Token、JWT
一、产生原因
浏览器的同源策略
同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
说简单点,同源策略就是浏览器本身的一种特殊属性,浏览器在访问资源时会在同源策略约束下,避免不同的站点相互之间轻易的获取信息。
所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开百度和谷歌的页面。浏览器的百度tab页执行脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。 如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
举个例子:比如一个恶意网站的页面通过iframe嵌入了银行的登录页面(二者不同源),
如果没有同源限制,恶意网页上的javascript脚本就可以在用户登录银行的时候获取用户名和密码。
何谓同源:URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示它们同源。
在浏览器中,<script>、<img>、<iframe>、<link>等标签都可以加载跨域资源,而不受同源限制,
但浏览器会限制脚本中发起的跨域请求。比如,使用 XMLHttpRequest 对象和Fetch发起 HTTP 请求就必须遵守同源策略。
Web 应用程序通过 XMLHttpRequest 对象或Fetch能且只能向同域名的资源发起 HTTP 请求,而不能向任何其它域名发起请求。
不允许跨域访问并非是浏览器限制了发起跨站请求,而是跨站请求可以正常发起,但是返回结果被浏览器拦截了。
最好的例子是CSRF跨站攻击原理,请求是发送到了后端服务器,无论是否设置允许跨域,
有些浏览器不允许从HTTPS跨域访问HTTP,比如Chrome和Firefox,这些浏览器在请求还未发出的时候就会拦截请求,这是特例。
二、跨域问题的解决方法
1、通过jsonp跨域
- JSONP是一个非官方协议,它允许在服务器端集成script tags返回至客户端,通过javascript callback的形式实现跨域访问。
- 基本思想:网页通过添加一个
<script>
元素,向服务器请求JSON数据,这种做法不受同源策略限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
<script type="text/javascript"> function jsonpCallback(result){ //alert(result); for(var i in result){ alert(i + ":" + result[i]); //循环输出 } } var JSONP = document.createElement("script"); JSONP.type = "text/javascript"; JSONP.src = "http://crossdomain.com/services.php?callback=jsonpCallback"; document.getElementsByTagName("head")[0].appendChild(JSONP); </script>
2、通过修改document.domain来跨子域
3、使用window.name来进行跨域
4、使用HTML5中新引进的window.postMessage方法来跨域传送数据
- HTML5引入了一个全新的API:跨文档消息传输Cross Document Messaging 。它的目标是在一个单独的持久连接上提供全双工、双向通信。(同源策略对web sockets不适用)
- web sockets原理:在JS创建了web sockets之后,会有一个HTTP请求发送到浏览器以发起连接。取得服务器响应后,建立的连接会使用HTTP升级从HTTP协议交换为web sockets协议。
-
otherWindow.postMessage(message, targetOrigin)
otherWindow:指目标窗口,也就是给哪个窗口发消息,是window.frames属性的成员或者由window.open方法创建的窗口。
参数说明:
(1)message:是要发送的消息,类型为string,object
(2)targetOrigin:是限定消息接收范围,不限制使用“ * ”
5、使用代理服务器,使用代理方式跨域更加直接,因为同源限制是浏览器实现的。如果请求不是从浏览器发起的,就不存在跨域问题了。
三、CSRF 攻击原理及防护
CSRF全称为跨站请求伪造(Cross-site request forgery),是一种网络攻击方式,也被称为 one-click attack 或者 session riding。
攻击原理 :CSRF攻击利用网站对于用户网页浏览器的信任,挟持用户当前已登陆的Web应用程序,去执行并非用户本意的操作。
图解:
CSRF攻击的原理:
①用户正常登录A银行网站,
②A网站返回cookie信息给用户,浏览器保存cookie信息
③在A网站没有退出登录的情况下(或者说cookie信息没过期), 登录了恶意网站B
④恶意网站B,提前准备好转账表单或者其它请求 ,将其隐藏. 把提交到A网站的按钮设置为一个"领取优惠券"的图片链接.用户 点击链接
⑤在用户主观未知的情况下,访问A网站,此时浏览器会自动携带cookie信息
⑥A网站识别到cookie信息,默认为是用户本人做出的请求,根据请求做出相应的操作.
⑦用户收到损失.
CSRF攻击防护:
1、API 仅接受json
2、验证HTTP Referer字段
3、在请求地址中添加token验证
- 在 HTTP 请求中以參数的形式添加一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,假设请求中没有token 或者 token 内容不对,则觉得可能是 CSRF 攻击而拒绝该请求。
- token须要足够随机
- 敏感的操作应该使用POST。而不是GET,以form表单的形式提交。能够避免token泄露。
在请求参数中加入一个混淆字符串csrf_token.
简单来说,服务器在接受到请求后, 返回给用户两个csrf_token值, 一个放在cookie信息中,浏览器会保存,下次请求的时候浏览器自动携带. 一个放在前端页面中(例如:表单域或者ajax的请求头中), 当用户再次向服务器发送数据的时候, 服务器会对比cookie中和前端页面中的csrf_token值,如果一样,证明是用户操作,如果不一样,证明是非法操作.
恶意网站B因为页面是提前写好的,无法获取到csrf_token值(cookie同源策略),所以服务器接受到请求的时候,会显示非法操作,从而保证了用户个人信息的安全.解决了csrf攻击
4、提交验证码
在表单中添加一个随机的数字或字母验证码。通过强制用户和应用进行交互。来有效地遏制CSRF攻击。
参考:
https://blog.csdn.net/diu_brother/article/details/88367029
https://www.cnblogs.com/wangpenghui522/p/6284355.html
https://www.cnblogs.com/well-666/p/12185098.html
https://blog.csdn.net/qq_42327755/article/details/80575565
https://www.jianshu.com/p/451e575a3a8a