Session和Cookie这两个概念,在学习java web开发之初,大多数人就已经接触过了。最近在研究跨域单点登录的实现时,发现对于Session和Cookie的了解,并不是很深入,所以打算写两篇文章记录一下自己的理解。在我们的应用集成Spring Session之前,先补充一点Session和Cookie的关键知识。

Session与Cookie基础

由于http协议是无状态的协议,为了能够记住请求的状态,于是引入了Session和Cookie的机制。我们应该有一个很明确的概念,那就是Session是存在于服务器端的,在单体式应用中,他是由tomcat管理的,存在于tomcat的内存中,当我们为了解决分布式场景中的session共享问题时,引入了redis,其共享内存,以及支持key自动过期的特性,非常契合session的特性,我们在企业开发中最常用的也就是这种模式。但是只要你愿意,也可以选择存储在JDBC,Mongo中,这些,spring都提供了默认的实现,在大多数情况下,我们只需要引入配置即可。而Cookie则是存在于客户端,更方便理解的说法,可以说存在于浏览器。Cookie并不常用,至少在我不长的web开发生涯中,并没有什么场景需要我过多的关注Cookie。http协议允许从服务器返回Response时携带一些Cookie,并且同一个域下对Cookie的数量有所限制,之前说过Session的持久化依赖于服务端的策略,而Cookie的持久化则是依赖于本地文件。虽然说Cookie并不常用,但是有一类特殊的Cookie却是我们需要额外关注的,那便是与Session相关的sessionId,他是真正维系客户端和服务端的桥梁。

代码示例

用户发起请求,服务器响应请求,并做一些用户信息的处理,随后返回响应给用户;用户再次发起请求,携带sessionId,服务器便能够识别,这个用户就是之前请求的那个。

使用Springboot编写一个非常简单的服务端,来加深对其的理解。需求很简单,当浏览器访问localhost:8080/test/cookie?browser=xxx时,如果没有获取到session,则将request中的browser存入session;如果获取到session,便将session中的browser值输出。顺便将request中的所有cookie打印出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Controller
public class CookieController {
 
@RequestMapping("/test/cookie")
public String cookie(@RequestParam("browser") String browser, HttpServletRequest request, HttpSession session) {
//取出session中的browser
Object sessionBrowser = session.getAttribute("browser");
if (sessionBrowser == null) {
System.out.println("不存在session,设置browser=" + browser);
session.setAttribute("browser", browser);
} else {
System.out.println("存在session,browser=" + sessionBrowser.toString());
}
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
for (Cookie cookie : cookies) {
System.out.println(cookie.getName() + " : " + cookie.getValue());
}
}
return "index";
}
}

我们没有引入其他任何依赖,看看原生的session机制是什么。

1 使用chrome浏览器,访问localhost:8080/test/cookie?browser=chrome,控制台输出如下:

1
Session Info: 不存在session,设置browser=chrome

既没有session,也没有cookie,我们将browser=chrome设置到session中。

再次访问同样的端点,控制台输出如下:

1
2
Session Info: 存在session,browser=chrome
Cookie Info: JSESSIONID : 4CD1D96E04FC390EA6C60E8C40A636AF

多次访问之后,控制台依旧打印出同样的信息。

稍微解读下这个现象,可以验证一些结论。当服务端往session中保存一些数据时,Response中自动添加了一个Cookie:JSESSIONID:xxxx,再后续的请求中,浏览器也是自动的带上了这个Cookie,服务端根据Cookie中的JSESSIONID取到了对应的session。这验证了一开始的说法,客户端服务端是通过JSESSIONID进行交互的,并且,添加和携带key为JSESSIONID的Cookie都是tomcat和浏览器自动帮助我们完成的,这很关键。

2 使用360浏览器,访问localhost:8080/test/cookie?browser=360

第一次访问:

1
Session Info: 不存在session,设置browser=360

后续访问:

1
2
Session Info: 存在session,browser=360
Cookie Info: JSESSIONID : 320C21A645A160C4843D076204DA2F40

为什么要再次使用另一个浏览器访问呢?先卖个关子,我们最起码可以得出结论,不同浏览器,访问是隔离的,甚至重新打开同一个浏览器,JSESSIONID也是不同的。另外可以尝试把保存session的操作注视掉,则可以发现Response中就不会返回JSESSIONID了,即这是一次无状态的请求。

安全问题

其实上述的知识点,都是非常浅显的,之所以啰嗦一句,是为了引出这一节的内容,以及方便观察后续我们引入Spring Session之后的发生的变化。

还记得上一节的代码示例中,我们使用了两个浏览器:

  • chrome浏览器访问时,JSESSIONID为4CD1D96E04FC390EA6C60E8C40A636AF,后端session记录的值为:browser=chrome。
  • 360浏览器访问时,JSESSIONID为320C21A645A160C4843D076204DA2F40,后端session记录的值为:browser=360。

我们使用chrome插件Edit this Cookie,将chrome浏览器中的JSESSIONID修改为360浏览器中的值

EditThisCookie

同样访问原来的端点:localhost:8080/test/cookie?browser=chrome,得到的输出如下:

1
2
存在session,browser=360
JSESSIONID : 320C21A645A160C4843D076204DA2F40

证实了一点,存放在客户端的Cookie的确是存在安全问题的,我们使用360的JSESSIONID“骗”过了服务器。毕竟,服务器只能通过Cookie中的JSESSIONID来辨别身份。(这提示我们不要在公共场合保存Cookie信息,现在的浏览器在保存Cookie时通常会让你确定一次)

下一篇文章,将正式讲解如何在应用中集成Spring Session。

转自:https://www.cnkirito.moe/2017/09/03/Re%EF%BC%9A%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E7%9A%84Spring%20Session(%E4%B8%80)/

(转)从零开始的Spring Session(一)的更多相关文章

  1. Re:从零开始的Spring Session(三)

    上一篇文章中,我们使用Redis集成了Spring Session.大多数的配置都是Spring Boot帮我们自动配置的,这一节我们介绍一点Spring Session较为高级的特性. 集成Spri ...

  2. Re:从零开始的Spring Session(二)

    上一篇文章介绍了一些Session和Cookie的基础知识,这篇文章开始正式介绍Spring Session是如何对传统的Session进行改造的.官网这么介绍Spring Session: Spri ...

  3. Re:从零开始的Spring Session(一)

    Session和Cookie这两个概念,在学习java web开发之初,大多数人就已经接触过了.最近在研究跨域单点登录的实现时,发现对于Session和Cookie的了解,并不是很深入,所以打算写两篇 ...

  4. 从零开始的Spring Session(一)

    Session和Cookie这两个概念,在学习java web开发之初,大多数人就已经接触过了.最近在研究跨域单点登录的实现时,发现对于Session和Cookie的了解,并不是很深入,所以打算写两篇 ...

  5. (38)Spring Boot分布式Session状态保存Redis【从零开始学Spring Boot】

    [本文章是否对你有用以及是否有好的建议,请留言] 在使用spring boot做负载均衡的时候,多个app之间的session要保持一致,这样负载到不同的app时候,在一个app登录之后,而访问到另外 ...

  6. 57. Spring 自定义properties升级篇【从零开始学Spring Boot】

    之前在两篇文章中都有简单介绍或者提到过 自定义属性的用法: 25.Spring Boot使用自定义的properties[从零开始学Spring Boot] 51. spring boot属性文件之多 ...

  7. 17、Spring Boot普通类调用bean【从零开始学Spring Boot】

    转载:http://blog.csdn.net/linxingliang/article/details/52013017 我们知道如果我们要在一个类使用spring提供的bean对象,我们需要把这个 ...

  8. 21. Spring Boot过滤器、监听器【从零开始学Spring Boot】

    转载:http://blog.csdn.net/linxingliang/article/details/52069490 上一篇文章已经对定义Servlet 的方法进行了说明,过滤器(Filter) ...

  9. 81. Spring Boot集成JSP疑问【从零开始学Spring Boot】

    [原创文章,转载请注明出处] 针对文章: ()Spring Boot 添加JSP支持[从零开始学Spring Boot] 有网友提了这么一些疑问: 1.Spring Boot使用jsp时,仍旧可以打成 ...

随机推荐

  1. spy-debugger 前端调试工具

    一站式页面调试.抓包工具.远程调试任何手机浏览器页面,任何手机移动端webview(如:微信,HybirdApp等).支持HTTP/HTTPS,无需USB连接设备.    Language: Engl ...

  2. YAML语法介绍

    官网YAML: http://yaml.org/ http://yaml.org/xml 参考链接: http://www.ruanyifeng.com/blog/2016/07/yaml.html? ...

  3. (转载)解决AndroidStudio导入项目在 Building gradle project info 一直卡住

    源地址http://blog.csdn.net/yyh352091626/article/details/51490976 Android Studio导入项目的时候,一直卡在Building gra ...

  4. Centos 升级 python

    昨天把redmine的测试环境给搞Over了,想了下,干脆直接把环境给整成docker化的,配置环境的时候,安装docker-compose需要python2.7支持. CentOS 6 系统默认 P ...

  5. DXP 内电层分割

    多层电路板中间层设置与内电层如何分割 多层电路板与一般的电路板不同之处在于,多层电路板除了顶层和底层之外,还有若干中间层,这些中间层可以是信号层(mid layer),也可以是内部电源/接地层(int ...

  6. msyql DATETIME类型和Timestamp之间的转换

    DATETIME -> Timestamp: UNIX_TIMESTAMP(...) Timestamp -> DATETIME: FROM_UNIXTIME(...) select da ...

  7. MatLab Load cv::Mat 导入数据

    我们有时候在项目中需要将OpenCV中的cv::Mat导入MatLab进行分析与处理,那么如果把数据转过去呢,我们的做法是首先将cv::Mat导出为txt文件,或者是yml文件,请参见我之前的博客Wr ...

  8. HOJ 2091 Chess(三维简单DP)

    Chess My Tags (Edit) Source : Univ. of Alberta Local Contest 1999.10.16 Time limit : 1 sec Memory li ...

  9. Alice, Bob, Oranges and Apples CodeForces - 586E

    E - Alice, Bob, Oranges and Apples CodeForces - 586E 自己想的时候模拟了一下各个结果 感觉是不是会跟橘子苹果之间的比例有什么关系 搜题解的时候发现了 ...

  10. 基础知识系列☞C#中→委托

    有些.NET中的高级特性,比如:委托! 有一种怎么也搞不懂的赶脚... 博客读了好几篇,代码也动手写了,书中的一些介绍也看了, 各种搜索关于委托的,至今还处于"会用"的阶段. 该怎 ...