定义:
1.Session (会话) : Session是服务器端用来存储用户信息的一种机制。当用户第一次访问网站时,服务器会为该用户创建一个唯一的session ID,并将该ID存储在Cookie中发送给客户端。客户端每次请求时都会携带这个session lD,服务器通过它来识别并关联用户的会话状态。服务器可以使用session来跟踪用户身份认证、保存用户数据等。
2.Cookie (HTTP Cookie) : Cookie是存储在客户端的小型文本文件,由服务器通过响应头中的Set-Cookie头部发送给客户端,并随后的每个请求中被浏览器自动携带。Cookie通常用来存储一些用户相关的信息,例如登录状态、用户首选项°等。服务器可以根据Cookie来识别用户,并提供个性化的服务。
3.Token (令牌I) :Token是一种安全凭证,用于验证用户身份和授权访问。与session和cookie不同,token是无状态的,即服务器不存储任何信息。在用户登录成功之后,服务器会生成一个token,并将其返回给客户端。客户端在每次请求时都需要携带这个token,服务器通过验证token的有效性来辨别用户身份和权限。
发展:
http最开始为了满足大家浏览web文档的请求只有GET请求,浏览完了就走,两个连接之间没有任何关系,这也是http无状态的原因。
但是后来我们需要购物、评论等,不是单纯的浏览web,需要我们记录下每次连接之间的关系,有了cookie
以加入购物车为例,每次浏览器请求后 server 都会将本次商品 id 存储在 Cookie 中返回给客户端,客户端会将 Cookie 保存在本地,下一次再将上次保存在本地的 Cookie 传给 server 就行了,这样每个 Cookie 都保存着用户的商品 id,购买记录也就不会丢失了
因为所有的信息已经存在server服务端了,所以cookie每次携带所有的信息会很长,有了session。在登录的时候,server会生成一个session,为用户分配一个sessionid,通过cookie传给server,在后端查找用户信息
但是session是单机登录的,一般为了高可用会有不止一台机器,通过负载均衡的方式决定请求到哪台机器上
解决方法:
方法1:A生成session后复制到bc上,缺点是数据比较冗余、性能消耗比较大
方法2:Nginx 的 sticky 模块。让每个客户端固定打到一个机器上,比如通过ip算hash值等。缺点是这台机器挂了就不能登录了
方法3:将session保存在redis中,redis做集群设置。缺点就是每个session都要从redis去查询,多了一次连接
token:首先请求方输入自己的用户名,密码,然后 server 据此生成 token,客户端拿到 token 后会保存到本地,之后向 server 请求时在请求头带上此 token 即可。
jwt:检验token
可以看到 token 主要由三部分组成:
header:指定了签名算法
payload:可以指定用户 id,过期时间等非敏感数据
Signature: 签名,server 根据 header 知道它该用哪种签名算法,再用密钥根据此签名算法对 head + payload 生成签名,这样一个 token 就生成了。
当 server 收到浏览器传过来的 token 时,它会首先取出 token 中的 header + payload,根据密钥生成签名,然后再与 token 中的签名比对,如果成功则说明签名是合法的,即 token 是合法的。而且你会发现 payload 中存有我们的 userId,所以拿到 token 后直接在 payload 中就可获取 userid,避免了像 session 那样要从 redis 去取的开销
优缺点:
token缺点(更适合一次性的命令认证,设置一个比较短的有效期):
太长:token比cookie长,每次请求中带上token对请求来说有负担
不太安全:token存在于浏览器的local storage中,而这类的本地存储可以被js直接获取。token生成要失效的话需要过期才行,就算检测到威胁也无法让其失效