一、session\token\cookie
1.产生背景
http是个无状态的请求,所以一个页面登录了,另一个页面,也不知道,为了解决网页共享数据,产生了session和cookie,以及替换者token
2.客户端和服务端通信:
客户端给服务端发消息
服务器端接受客户端请求后,建立一个session,并发送一个http响应到客户端,这个响应头,其中就包含Set-Cookie头部。该头部包含了sessionId。
在客户端发起的第二次请求,假如服务器给了set-Cookie,浏览器会自动在请求头中添加cookie
服务器接收请求,分解cookie,验证信息,核对成功后返回response给客户端
3.cookie
cookie就是写在客户端的一个txt文件,cookie有状态,不允许垮域访问的
-
cookie最大4k,一般浏览器最多20个,存在于客户端,
-
CSRF(跨站请求伪造)攻击,这个也好解决,很多框架都屏蔽这个问题
-
有的客户端不支持cookie,需要手动设置,比如小程序
-
浏览器对cookie有限制,不能手动设置cookie,对于混合嵌套的开发有问题,比如小程序跳转H5页面,不能携带cookie
-
Expire属性缺省时,表示会话性cookie,值保存在客户端内存中,并在用户关闭浏览器时失效。需要注意的是,有些浏览器提供了会话恢复功能,这种情况下即使关闭了浏览器,会话期 Cookie 也会被保留下来,就好像浏览器从来没有关闭一样。与会话性 Cookie 相对的是持久性 Cookie,持久性 Cookies 会保存在用户的硬盘中,直至过期或者清除 Cookie。这里值得注意的是,设定的日期和时间只与客户端相关,而不是服务端.
-
Max-Age 用于设置在 Cookie 失效之前需要经过的秒数,正数时,浏览器会将其持久化(即写到对应的 Cookie 文件中);负数,则表示该 Cookie 只是一个会话性 Cookie,为 0 时,则会立即删除这个 Cookie。假如 Expires 和 Max-Age 都存在,Max-Age 优先级更高。
-
Domain
Domain 指定了 Cookie 可以送达的主机名。假如没有指定,那么默认值为当前文档访问地址中的主机部分(但是不包含子域名)在这里注意的是,不能跨域设置 Cookie -
Path
Path 指定了一个 URL 路径,这个路径必须出现在要请求的资源的路径中才可以发送 Cookie 首部 -
Secure属性
标记为 Secure 的 Cookie 只应通过被HTTPS协议加密过的请求发送给服务端。使用 HTTPS 安全协议,可以保护 Cookie 在浏览器和 Web 服务器间的传输过程中不被窃取和篡改。 -
HTTPOnly
设置 HTTPOnly 属性可以防止客户端脚本通过 document.cookie 等方式访问 Cookie,有助于避免 XSS 攻击。 -
SameSite
SameSite 是最近非常值得一提的内容,因为 2 月份发布的 Chrome80 版本中默认屏蔽了第三方的 Cookie
Strict 仅允许一方请求携带 Cookie,即浏览器将只发送相同站点请求的 Cookie,即当前网页 URL 与请求目标 URL 完全一致。
Lax 允许部分第三方请求携带 Cookie
None 无论是否跨站都会发送 Cookie
之前默认是 None 的,Chrome80 后默认是 Lax。
跨域和跨站
首先要理解的一点就是跨站和跨域是不同的。同站(same-site)/跨站(cross-site)」和第一方(first-party)/第三方(third-party)是等价的。但是与浏览器同源策略(SOP)中的「同源(same-origin)/跨域(cross-origin)」是完全不同的概念。
同源策略的同源是指两个 URL 的协议/主机名/端口一致。例如,https://www.taobao.com/pages/…,它的协议是 https,主机名是 www.taobao.com,端口是 443。
同源策略作为浏览器的安全基石,其「同源」判断是比较严格的,相对而言,Cookie中的「同站」判断就比较宽松:只要两个 URL 的 eTLD+1 相同即可,不需要考虑协议和端口。其中,eTLD 表示有效顶级域名,注册于 Mozilla 维护的公共后缀列表(Public Suffix List)中,例如,.com、.co.uk、.github.io 等。eTLD+1 则表示,有效顶级域名+二级域名,例如 taobao.com 等。
举几个例子,www.taobao.com 和 www.baidu.com 是跨站,www.a.taobao.com 和 www.b.taobao.com 是同站,a.github.io 和 b.github.io 是跨站(注意是跨站)。
4.session
session存在于服务端,
- 负载均衡多服务器的情况,不好确认当前用户是否登录,因为多服务器不共享seesion。这个问题也可以将session存在一个服务器中来解决,但是就不能完全达到负载均衡的效果。
- 每个客户端只需存储自己的session id,但是服务端却需要存储所有用户session id,对服务器也是一个压力
cookie只是实现session的其中一种方案。虽然是最常用的,但并不是唯一的方法。禁用cookie后还有其他方法存储,比如放在url中\通过LocalStorage的方式
5.token
组成:uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名)
最小的token都比cookie大,无状态,允许垮域访问的
token在客户端一般存放于localStorage,cookie,或sessionStorage中。在服务器一般存于数据库中
服务端把用户信息加密(token)传给客户端,客户端每次访问都返回token,服务端解密token,就知道这个用户是谁了。通过cpu加解密,服务端就不需要存储session id占用存储空间,就很好的解决负载均衡多服务器的问题了。这个方法叫jwt
使用jwt有一个问题,就是不像cookie和session有自动过期的设置,这个token的状态和过期时间需要自己手动设置。比如说,token中存储用户登录的时间,服务端每次验证这个时间是否过期就可以了
注:
无状态和有状态的区别:和不和服务器端进行数据交换!!!