一、前置内容
1.1回顾HTTP协议
HTTP协议有五个特点:
1.2为什么会有这些东西
HTTP协议是无状态协议,所谓的无状态是指:客户端每次想要与服务端通信,都必须重新与服务端链接,意味着请求一次客户端和服务端就连接一次,下一次请求与上一次请求是无关的。
这种无状态的方式就会存在一个问题:如何判断两次请求是同一个人?为了解决这个问题。我们就迫切需要一种方式知道发起请求的客户端是谁?此时就有了这些东西,它们就可以解决客户端标识的问题。
二、cookie
cookie是保存在客户端或者浏览器端的一小块数据,大小限制在4KB左右。
接下来具体介绍一下,是如何通过cookie来实现用户确定或者权限确定。以网站用户登录操作为例:
我们可以看到大致分为以下几个步骤:
1.客户端发送请求到服务端(比如登录请求)
2.服务端收到请求后生成一个session会话
3.服务端响应客户端,并在响应头中设置Set-Cookie
4.客户端收到请求后,如果服务器给了Set-Cookie,那么下次浏览器就会在请求头中自动携带cookie
5.客户端发送其它请求,自动携带cookie,cookie中携带有用户信息等。
6.服务端接收到请求,验证cookie信息。比如通过sessionId来判断是否存在会话,存在则正常响应。
三、session
描述session:
session 由服务端创建,当一个请求发送到服务端时,服务器会检索该请求里面有没有包含 sessionId 标识,如果包含了 sessionId,则代表服务端已经和客户端创建过 session,然后就通过这个 sessionId 去查找真正的 session,如果没找到,则为客户端创建一个新的 session,并生成一个新的 sessionId 与 session 对应,然后在响应的时候将 sessionId 给客户端,通常是存储在 cookie 中。如果在请求中找到了真正的 session,验证通过,正常处理该请求。
总之每一个客户端与服务端连接,服务端都会为该客户端创建一个 session,并将 session 的唯一标识 sessionId 通过设置 Set-Cookie 头的方式响应给客户端,客户端将 sessionId 存到 cookie 中。
通常情况下,我们 cookie 和 session 都是结合着来用,当然你也可以单独只使用 cookie 或者单独只使用 session,这里我们就将 cookie 和 session 结合着来用。过程图如下:
四、cookie和session的区别
从前面可以看出,cookie和session之间主要是通过sesssionId关联起来的,所以:sessionId是cookie和session之间的桥梁。换个说法,session是基于cookie实现的,它们有如下特点:
- session比cookie更加安全,因为session存在服务端,而cookie存在客户端
- cookie只支持存储字符串数据,session可以存储任意数据
- cookie的有效期可以设置较长时间,session有效期都比较短
- session存储空间很大,cookie有限制
五、token
前面我们说的 sessionId 可以叫做令牌,令牌顾名思义就是确认身份的意思,服务端可以通过令牌来确认身份。
使用cookie和session有以下缺点:
- 增加请求体积,浪费性能,因为每次请求都会携带 cookie。
- 增加服务端资源消耗,因为每个客户端连接进来都需要生成 session,会占用服务端资源的。
- 容易遭受 CSRF 攻击,即跨站域请求伪造。
所以就有了民间的认证方式,token方式
1.token的组成
token 其实就是一串字符串而已,只不过它是被加密后的字符串,它通常使用 uid(用户唯一标识)、时间戳、签名以及一些其它参数加密而成。我们将 token 进行解密就可以拿到诸如 uid 这类的信息,然后通过 uid 来进行接下来的鉴权操作。
2.token是如何生成的?
前面我们说 cookie 是服务端设置了 set-cookie 响应头之后,浏览器会自动保存 cookie,然后下一次发送请求的时候会自动把 cookie 携带上。但是我们说 cookie 算是一种民间的实现方式,所以说浏览器自然不会对它进行成么处理。token 主要是由服务器生成,然后返回给客户端,客户端手动把 token 存下来,比如利用 localstorage 或者直接存到 cookie 当中也行。
3.token认证流程:
- 客户端发送请求,比如用户输入用户名和密码后登录
- 服务器端校验用户名和密码后,将用户id和其它信息进行加密,生成token
- 服务端将token响应给客户端
- 客户端收到响应后将token存储下来
- 下一次发送请求后需要将token携带上,比如放在请求头中或者其他地方
- 服务端取到token后校验,校验通过后则正常返回数据
用图进行显示,如下:
六、总结
总结下来就是:session 是空间换时间,token 是时间换空间。