前言
前几天思考了一下session跟cookies的关系和原理 发现以前对session跟cookies的理解一直都有误 以前我一直以为session是存在服务端 cookies存在客户端 他们的键值对是一一对应关系的 后来想了想 这其实是不完全对的
session和cookies的位置
之前我们说到我们需要一种跟踪和认证客户端的机制 这种机制在客户端处表现为cookies
cookies可以保存在浏览器缓存 磁盘中等等
这种机制在服务端表现为session
session可以保存在内存 缓存 memcache redis或者磁盘中等等
这些都是没问题的
cookies和session的对应关系
cookies和session上的键值对其实不是一一对应关系的 甚至可以说关系不大
我们使用java的servlet来举例子 就可以比较清楚的说明他们的关系
在我们服务端这边cookies和session不是一回事 而且它们都可以被我们服务端分别进行操作
设置cookies
在java servlet中 给http response增加一个键值对 {“login”; “mylogin”}1
2
3
4
5protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// add cookies
Cookie login = new Cookie("login", "mylogin");
resp.addCookie(login);
}
客户端那边的效果 成功设置这个键值对到cookies中
cookies原理
设置session
然后我给session对象设置一个键值对 在java servlet中给session设置键值对叫做setAttribute 设置键值对{“login”: “this is my login session”}1
2
3
4
5protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// add session attribute
HttpSession session = req.getSession();
session.setAttribute("login", "this is my login session");
}
然后我们在客户端的http response的cookies中发现新增了以下这个键值对
只是新建了一个key为jsessionid的键值对 跟我们设置的session attribute毫无关系
其实事实是
服务端这边是很节省资源的 它不是建立TCP连接之后就直接给客户端简历一个session 而是执行到如下语句1
HttpSession session = req.getSession();
这时候才给客户端新建一个session对象(如果没有session则新建一个session 如果有则返回) 这个session对象含有一个attribute map一个映射表来存储我们给session设置的一些键值对 当我们set attribute之后 这些键值对存在attribute map之中 并且会http response新建一个特别的键值对
这个键值对就是我们上面看到的那个跟我们设置的session attribute毫无关系的cookies键值对
这个jsessionid的cookies值顾名思义就是在cookies中用来标记这个客户端属于哪个session的唯一属性
所以说我们设置的所有session attribute都是存在服务端的本地的 给客户端那边传送过去关于session那部分的内容仅仅只是一个用来标识客户端所属session的session id 而session的所有内容都是存在服务端本地 之后对于每次客户端的请求 服务端都可以根据它请求头的session id这个cookie值(名字因所用框架有别 上面使用servlet 是jsessionid)来证明它是那个session的 然后根据这个session id在内存缓存memcache或者redis中找到这个session 继而找到这个session用来存键值对(就是attributes)的attribute map 从而找到我们在session中设置的内容
所以说cookies和session的内容 本质上除了需要在cookies上设置一个session id的cookies值来标记客户端所属session 其他基本毫无关系的 更不存在以前理解的一一对应关系
session原理
综上所述
- cookies是一种存储在客户端的 对客户端进行跟踪和认证的机制
- session是一种存储在服务端的 对客户端进行跟踪和认证的机制 session的设置需要给cookies设置一个特殊的sessionid字段值
- 对于服务端开发者来说 这两种机制都是可选的 并且是可以结合使用的 但是他们之间不是一回事