Cookie和Session
cookie
和 session
是网站和服务器交互过程中用到的概念。HTTP协议本身是无状态的,也就是两次不同的HTTP请求发出后,服务器端并不知道发起者是否是同一个用户:比如用户登录后查看自己的信息,然后查看自己的一些交易记录。那么如何记录类似的状态,常见的有两种:
- 我们现在大部分API请求所用的,请求中将相关信息放到请求参数中,比如用户登录后获得了
userId
,那么我们就可以在用户发起上述两个API请求时,将userId
放入请求参数中即可。 - 依靠
session
机制。
下面就主要来说明 session
机制。
session
只是逻辑概念,表示一次会话,会话过程是从访问网站开始到关闭浏览器的过程。但我觉得更准确地来说,session
会话生命周期由其实现方式决定。
有了 session
这个逻辑概念后,我们可以认为每个用户访问时都是一个单独的会话过程,只要该会话周期没有过期,那么该过程中不同用户执行的所有操作我们都可以区分出来,也就是相当于拥有了状态(这里就可以指登录状态)。
session会话实现
上文说了,session
只是逻辑概念,具体实现可以有多种方式。只要我们能够为每一个用户建立一个唯一的"会话"即可,如何建立呢?
每次API请求都需要服务器识别是哪一个用户,所以服务器端肯定要对本次会话的唯一ID进行存储。反过来,客户端每次发起请求,也都要告诉服务器该次会话的ID,这样双方才能确认本次会话是属于哪一个用户。
所以这就引出了客户端如何存储会话ID和服务器端如何存储会话ID?
客户端存储会话ID
客户端的会话ID存储和网站代码具体实现有关。但是由于浏览器本身提供了一种叫做 cookie
的机制,在该机制下,服务器可以将用户登录后的会话ID存储在 cookie
中,以后每次API请求时,浏览器都会自动将该 会话ID
发送到服务器。所以客户端一般选择采用 cookie
机制存储会话ID。
因为双方通信时基于HTTP
协议的,服务器在返回给前端网站响应时,只需要设置set-cookie:*****
,浏览器就知道需要把该信息存下来。
cookie
除了存储数据外,还可以设置数据的过期时间,时间到了自动过期。
cookie
存储在哪里?根据过期时间的不同而不同。如果cookie
自动过期时间设置为0,那么就存储在浏览器内存中,也就是关闭了浏览器就没了。如果过期时间设置成其他,那么就算关闭了浏览器,只要过期时间没到,再下次打开浏览器的时候,该cookie
也是存在的。
最后,看一下,cookie
具体是什么格式?
这是截取访问知乎时,浏览器中存储的 cookie
,简单看就是键值对,其他属性具体开发时再描述。
服务器端存储会话ID
会话ID对于服务器来说不仅仅是一个ID,服务器还可以把它和其他信息关联起来,形成一个键值对,比如
{
"sessionId":{
"name":"Tom",
"age":"24"
}
}
提这个是指,服务器可以在需要的时候把一些信息和会话ID关联起来,然后一同存储。
服务器端存储的方式就更多了,可以存放在服务器内存中,可以存放在文件中(比如每个会话ID生成一个文件,文件里面保存需要关联的信息),可以存放在数据库中等等。
但是,我们最常用的是结合 redis
,因为 redis
本身是K-V键值对存储结构,并且 redis
中的键可以设置自动过期时间,非常适合于缓存。所以很多数据库前级加缓存也是用到了 redis
。
所以,服务器端将会话ID和其相关信息组成的键值对存储在 redis
中,并对其配置过期时间,就可以达到缓存用户会话的目的。
小结
总体流程大致如下