Cookie的机制
浏览器访问网站后, UA(User Agent), 这些网站一般会存放在客户端一些数据, 用于跟踪或者为了后续的智能广告推送等,实现一些自定义的功能.
Domin和Path标识是那个网站发送给浏览器的, Expires属性标识有效时间, 过期则自动删除(目前国内一些流氓厂商可能将时间设计为很多很多年,为了做追踪),如果没设置时间则关闭浏览器后自动删除Cookie.
Session
Session存放在服务端HashTable结构, 当浏览器发送一次请求后,服务器自动生成Session ID用来标识一个HashTable, 通过相应发送给浏览器. 当第二次发送请求,会将前一次服务器响应中的 Session ID 放在请求中一并发送到服务器上,服务器从请求中提取出 Session ID,并和保存的所有 Session ID 进行对比,找到这个用户对应的 HashTable。一般情况下,服务器会在一定时间内(默认 20 分钟)保存这个 HashTable,过了时间限制,就会销毁这个 HashTable。在销毁之前,程序员可以 将用户的一些数据以 Key 和 Value 的形式暂时存放在这个 HashTable 中。当然,也有使用数据库将这个 HashTable 序列化后保存起来的,这 样的好处是没了时间的限制,坏处是随着时间的增加,这个数据库会急速膨胀,特别是访问量增加的时候。一般还是采取前一种方式,以减轻服务器压力。
总结
http是无状态协议,为了能记住请求状态,于是引入了Session和Cookie机制.我们应该有一个很明确的概念,那就是 Session 是存在于服务器端的,在单体式应用中,他是由 tomcat 管理的,存在于 tomcat 的内存中,而 Cookie 则是存在于客户端,更方便理解的说法,可以说存在于浏览器。Cookie 并不常用,至少在企业或者互联网开发中,并没有什么场景需要我们过多的关注 Cookie。http 协议允许从服务器返回 Response 时携带一些 Cookie,并且同一个域下对 Cookie 的数量有所限制,之前说过 Session 的持久化依赖于服务端的策略,而 Cookie 的持久化则是依赖于本地文件。虽然说 Cookie 并不常用,但是有一类特殊的 Cookie 却是我们需要额外关注的,那便是与 Session 相关的 sessionId,他是真正维系客户端和服务端的桥梁.
遇到问题
当在项目中引入Srping Security 或 Shiro, 在Spring boot 下可能会报一个这样的错误 : (基本从错误堆栈可以看出是安全框架的事情)# 该请求被拒绝,因为该URL包含潜在的恶意字符串“;” org.springframework.security.web.firewall.RequestRejectedException:The request was rejected because the URL contained a potentially malicious String ";"
解决方案
- springboot项目的yml配置文件中增加
server: port: 80 servlet: session: tracking-modes: cookie cookie: http-only: true
- 启动类继承 SpringBootServletInitializer 类(extends SpringBootServletInitializer),重写 onStartup 方法
public void onStartup(ServletContext servletContext)throws > ServletException { super.onStartup(servletContext); servletContext.setSessionTrackingModes(Collections.singleton(SessionTrackingMode.COOKIE)); SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig(); sessionCookieConfig.setHttpOnly(true); }
PS : Shiro 有空再写