写在前面
这里是小飞侠Pan🥳,立志成为一名优秀的前端程序媛!!!
本篇博客收录于我的github前端笔记仓库中,持续更新中,欢迎star~
👉https://github.com/mengqiuleo/myNote
Cookie
Cookie
是一种存储机制,
当我们第一次请求网页内容的时候是没有任何cookie的,服务器在收到请求以后会在HTTP响应里添加头部Set-Cookie,并且在Set-cookie里进行标识,在下一次请求的时候浏览器就会在HTTP请求里添加头部Cookie,并且用上Set-Cookie里的标识,这样服务器就可以给不同用户匹配不同的内容了。
因为每一次浏览器请求都要带上Cookie,因此就把Cookie设计的很小,不能超过4KB,但大部分情况会更小。
通常,它用于判断两个请求是否来自于同一个浏览器,例如用户保持登录状态。
Cookie 主要用于下面三个目的
会话管理
登陆、购物车、游戏得分或者服务器应该记住的其他内容
个性化
用户偏好、主题或者其他设置
追踪
记录和分析用户行为
HTTP Cookie 机制是 HTTP 协议无状态的一种补充和改良
Cookie的特性:
- Cookie一旦创建成功,名称就无法修改
- Cookie是无法跨域名的,也就是说a域名和b域名下的cookie是无法共享的,这也是由Cookie的隐私安全性决定的,这样就能够阻止非法获取其他网站的Cookie
- 每个域名下Cookie的数量不能超过20个,每个Cookie的大小不能超过4kb
- 有安全问题,如果Cookie被拦截了,那就可获得session的所有信息,即使加密也于事无补,无需知道cookie的意义,只要转发cookie就能达到目的
- Cookie在请求一个新的页面的时候都会被发送过去
如果需要域名之间跨域共享Cookie,有两种方法:
- 使用Nginx反向代理
- 在一个站点登陆之后,往其他网站写Cookie。服务端的Session存储到一个节点,Cookie存储sessionId
Cookie的使用场景:
- 最常见的使用场景就是Cookie和session结合使用,我们将sessionId存储到Cookie中,每次发请求都会携带这个sessionId,这样服务端就知道是谁发起的请求,从而响应相应的信息。
- 可以用来统计页面的点击次数
LocalStorage
LocalStorage是HTML5新引入的特性,由于有的时候我们存储的信息较大,Cookie就不能满足我们的需求,这时候LocalStorage就派上用场了。
LocalStorage的优点:
- 在大小方面,LocalStorage的大小一般为5MB,可以储存更多的信息
- LocalStorage是持久储存,并不会随着页面的关闭而消失,除非主动清理,不然会永久存在
- 仅储存在本地,不像Cookie那样每次HTTP请求都会被携带
LocalStorage的缺点:
- 存在浏览器兼容问题,IE8以下版本的浏览器不支持
- 如果浏览器设置为隐私模式,那我们将无法读取到LocalStorage
- LocalStorage受到同源策略的限制,即端口、协议、主机地址有任何一个不相同,都不会访问
LocalStorage的使用场景:
- 有些网站有换肤的功能,这时候就可以将换肤的信息存储在本地的LocalStorage中,当需要换肤的时候,直接操作LocalStorage即可
- 在网站中的用户浏览信息也会存储在LocalStorage中,还有网站的一些不常变动的个人信息等也可以存储在本地的LocalStorage中
SessionStorage
SessionStorage和LocalStorage都是在HTML5才提出来的存储方案,SessionStorage 主要用于临时保存同一窗口(或标签页)的数据,刷新页面时不会删除,关闭窗口或标签页之后将会删除这些数据。
SessionStorage与LocalStorage对比:
- SessionStorage和LocalStorage都在本地进行数据存储;
- SessionStorage也有同源策略的限制,但是SessionStorage有一条更加严格的限制,SessionStorage只有在同一浏览器的同一窗口下才能够共享;
- LocalStorage和SessionStorage都不能被爬虫爬取;
SessionStorage的使用场景
- 由于SessionStorage具有时效性,所以可以用来存储一些网站的游客登录的信息,还有临时的浏览记录的信息。当关闭网站之后,这些信息也就随之消除了。
Cookie、LocalStorage、SessionStorage区别
浏览器端常用的存储技术是 cookie 、localStorage 和 sessionStorage。
- **cookie:**其实最开始是服务器端用于记录用户状态的一种方式,由服务器设置,在客户端存储,然后每次发起同源请求时,发送给服务器端。cookie 最多能存储 4 k 数据,它的生存时间由 expires 属性指定,并且 cookie 只能被同源的页面访问共享。
- **sessionStorage:**html5 提供的一种浏览器本地存储的方法,它借鉴了服务器端 session 的概念,代表的是一次会话中所保存的数据。它一般能够存储 5M 或者更大的数据,它在当前窗口关闭后就失效了,并且 sessionStorage 只能被同一个窗口的同源页面所访问共享。
- **localStorage:**html5 提供的一种浏览器本地存储的方法,它一般也能够存储 5M 或者更大的数据。它和 sessionStorage 不同的是,除非手动删除它,否则它不会失效,并且 localStorage 也只能被同源页面所访问共享。
上面几种方式都是存储少量数据的时候的存储方式,当需要在本地存储大量数据的时候,我们可以使用浏览器的 indexDB 这是浏览器提供的一种本地的数据库存储机制。它不是关系型数据库,它内部采用对象仓库的形式存储数据,它更接近 NoSQL 数据库。
Session
实际上我们打开浏览器是可以看到保存了哪些Cookie,也就是说如果把用户名和密码放在Cookie是很不安全的,只要电脑被黑,在Cookie里的重要信息就会被泄漏,于是就有了Session(会话)。
浏览器访问服务器就是会话的开始,不同的网站对于每一个用户的会话都设置了时间(这里的时间是结束会话的时间)以及唯一的ID(这里的ID就是Session ID),因为时间和ID是服务器自己定义的东西,所以一般会保存在数据库里,Session ID 通常是一串没有规律的字符串。
当浏览器将用户名和密码发送给服务器后,服务器会把Session ID和会话结束时间发送给浏览器,这里就用到了Cookie,设置Cookie,并将Session ID加到Cookie中,再把会话结束时间对应设置为这个Cookie的有效期,浏览器拿到Cookie后进行保存,此时浏览器没有保存用户名和密码,保存的Session ID也是没有规律的字符串,Cookie里也就只有Session ID 最重要,(如果黑客入侵拿到了Session ID ,因为Session ID也是没有规律的字符串,所以黑客无法依据Session ID 推断出用户的密码。其次,服务器在发送Cookie之前,会对Session ID进行签名,回句话说,当黑客修改了Session ID,Session ID 就会变成服务器识别不了的字符串)。浏览器的以后的每次访问都会自动发送这个Session ID给服务器,直到Cookie 的有效期失效后,浏览器一般会自行删除这个Cookie,此时会话结束。那么在Cookie失效后,用户就得重新输入用户名和密码了。
在每次请求时,服务器都会从会话 中读取 SessionId,如果服务端的数据和读取的 SessionId 相同,那么服务器就会发送响应给浏览器,允许用户登录。
Session 的缺点
Session 机制有个缺点,比如 A 服务器存储了 Session,就是做了负载均衡后,假如一段时间内 A 的访问量激增,会转发到 B 进行访问,但是 B 服务器并没有存储 A 的 Session,会导致 Session 的失效。
JWT
JSON Web Token
与普通Token一样,都是访问资源的令牌,都可以记录用户信息,都是只有验证成功后才可以获取信息。
不同的是普通Token服务端验证token信息要进行数据的查询操作;JWT验证token信息就不用,在服务器端使用秘钥校验就可以,不用数据库的查询。
流程:
当用户首次登录页面后,服务器就会生成一个JWT,服务器不需要保存这个JWT,只需要保存JWT签名的密文,接着把JWT发送给浏览器,浏览器将JWT用Cookie或Storage形式进行存储。然后用户每次发送请求都会把这个JWT发给服务器,用户就不需要重新输入账号密码了。
- 支持跨域访问:cookie是无法跨域的,而token由于没有用到cookie(前提是将token放到请求头中),所以跨域后不会存在信息丢失问题
- 无状态:token机制在服务端不需要存储session信息,因为token自身包含了所有登录用户的信息,所以可以减轻服务端压力
- 更适用CDN:可以通过内容分发网络请求服务端的所有资料
- 更适用于移动端:当客户端是非浏览器平台时,cookie是不被支持的,此时采用token认证方式会简单很多
- 无需考虑CSRF:由于不再依赖cookie,所以采用token认证方式不会发生CSRF,所以也就无需考虑CSRF的防御
JWT 主要由三部分组成,每个部分用 .
进行分割,各个部分分别是
Header
:声明需要用什么算法来生成签名Payload
:放一些特定的数据,比如有效期之类的Signature
一个简单的JWT的组成:xxxx.yyyy.zzzz
。
Signture
:header和payload两部分的内容会经由Base编码,另外在服务器端会保存一个密钥(secret),header和payload两部分组成的密码
和 服务器端的密码
进行算法运算最终得到签名信息(signture)
注意JWT每部分的作用,在服务端接收到客户端发送过来的JWT token之后:
header和payload可以直接利用base64解码出原文,从header中获取哈希签名的算法,从payload中获取有效数据
signature由于使用了不可逆的加密算法,无法解码出原文,它的作用是校验token有没有被篡改。服务端获取header中的加密算法之后,利用该算法加上secretKey对header、payload进行加密,比对加密后的数据和客户端发送过来的是否一致。注意secretKey只能保存在服务端,而且对于不同的加密算法其含义有所不同,一般对于MD5类型的摘要加密算法,secretKey实际上代表的是盐值