由于HTTP是一种无状态的协议,所以当我打开淘宝,登录后,点击跳转结账(另一个页面),服务器端就不知道现在发请求的是不是我了,就得让我再次登录来确认身份。所以每一次请求的发生都是全新的,那么就需要一个来记录身份并且验证的东西,相对于通行证一样。这就需要会话跟踪,Cookie和Session就是起这个作用,会话跟踪参考四种会话跟踪
Cookie和Session流程
- 客户端首次发出请求,服务器端收到后开辟一块 Session 空间(创建了Session对象),同时生成一个 sessionId ,并通过响应头的 **Set-Cookie:JSESSIONID=XXXXXXX **命令,向客户端发送要求设置 Cookie 的响应;
- 客户端收到响应后,在本机客户端设置了一个 **JSESSIONID=XXXXXXX **的 Cookie 信息,该 Cookie 的过期时间为浏览器会话结束;
- 后面每次客户端请求,都会携带Cookie信息,服务器端收到Cookie,会根据JSESSIONID是否一致去确认是否为本人。
参考1 参考2
Token
cookie和session实际上是同一套认证流程,相辅相成。session保存在服务器,cookie保存在客户端。最常见的做法就是客户端的cookie仅仅保存一个sessionID,这个sessionID是一个毫无规则的随机数,由服务器在客户端登录通过后随机生产的。往后,客户端每次访问该网站都要带上这个由sessionID组成的cookie。服务器收到请求,首先拿到客户端的sessionID,然后从服务器内存中查询它所代表的客户端(用户名,用户组,有哪些权限等)。
与token相比,这里的重点是,服务器必须保存sessionID以及该ID所代表的客户端信息。这些内容可以保存在内存,也可以保存到数据库(通常是内存数据库)。
而token则可以服务器完全不用保存任何登录信息。
token的流程是这样的。客户端登录通过后,服务器生成一堆客户端身份信息,包括用户名、用户组、有那些权限、过期时间等等。另外再对这些信息进行签名。之后把身份信息和签名作为一个整体传给客户端。这个整体就叫做token。之后,客户端负责保存该token,而服务器不再保存。客户端每次访问该网站都要带上这个token。服务器收到请求后,把它分割成身份信息和签名,然后验证签名,若验证成功,就直接使用身份信息(用户名、用户组、有哪些权限等等)。
可以看出,相对于cookie/session机制,token机制中,服务器根本不需要保存用户的身份信息(用户名、用户组、权限等等)。这样就减轻了服务器的负担。
我们举个例来说,假如目前有一千万个用户登录了,在访问不同的网页。如果用cookie/session,则服务器内存(或内存数据库)中要同时记录1千万个用户的信息。每次客户端访问一个页面,服务器都要从内存中查询出他的登录信息。而如果用token,则服务器内存中不记录用户登录信息。它只需要在收到请求后,直接使用客户端发过来的登录身份信息。
可以这么说,cookie/session是服务器说客户端是谁,客户端才是谁。而token是客户端说我(客户端)是谁,我就是谁。当然了,token是有签名机制的。要是客户端伪造身份,签名通不过。这个签名算法很简单,就是将客户端的身份信息加上一个只有服务器知道的盐值(不能泄露),然后进行md5散列算法(这里只是简化,方便理解,实际细节要稍复杂一些)。
cookie/session在单服务器,单域名时比较简单,否则的话,就要考虑如何将客户端的session保存或同步到多个服务器。还要考虑一旦宕机,内存中的这些信息是否会丢失。token因为服务器