【WEB系列】 Session与Cookie

文章目录
  1. 项目配置
    1. 1. 依赖
    2. 2. 启动入口
  2. Session/Cookie使用姿势
    1. 1. 登录入口,保存session
    2. 2. session读取测试
    3. 3. 退出登录
    4. 4. session实现原理
  3. 不能错过的源码和相关知识点
    1. 0. 项目
    2. 1. 微信公众号: 一灰灰Blog

虽然我们现在基本上已经进入了分布式session的时代了,但是在切实去看最新的oauth, sso, jwt等各种登录方案之前,我们有必要学习一下最早的cookie/session方案,看一下它们是怎么协同工作的,又有什么局限性

项目配置

1. 依赖

首先搭建一个标准的SpringBoot项目工程,相关版本以及依赖如下

本项目借助SpringBoot 2.2.1.RELEASE + maven 3.5.3 + IDEA进行开发

1
2
3
4
5
6
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

2. 启动入口

我们使用默认的配置进行测试,因此启动入口也可以使用最基础的

1
2
3
4
5
6
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}

Session/Cookie使用姿势

接下来我们再看一下如何在SpringBoot项目中是session/cookie

1. 登录入口,保存session

首先我们设计一个登录的接口,用来模拟真实场景下的登录,注意下面的实现

1
2
3
4
5
6
7
8
9
@RestController
public class SessionController {

@RequestMapping(path = "/login")
public String login(String uname, HttpSession httpSession) {
httpSession.setAttribute("name", uname);
return "欢迎登录:" + uname;
}
}

在上面的实现中,方法中定义了一个HttpSession的参数类型,具体的实现中,就是表示写入sesion的操作

当session写入完毕之后,在这个会话结束之前,后续的所有请求都可以直接获取到对应的session

2. session读取测试

下面给出两种常见的session获取方式

  • 直接从HttpSession中获取
  • 通过HttpServletRequest来获取
1
2
3
4
5
6
7
8
9
@RequestMapping("time")
public String showTime(HttpSession session) {
return session.getAttribute("name") + " ,当前时间为:" + LocalDateTime.now();
}

@RequestMapping("name")
public String showName(HttpServletRequest request) {
return "当前登录用户:" + request.getSession().getAttribute("name");
}

接下来我们来模拟验证一下

从上面的演示图中,也可以看出,在登录之后,访问上面的接口,可以直接拿到session中存储的用户名;

且不同用户登录(不同的浏览器),他们的session不会出现串掉的情况

3. 退出登录

有登陆当然就有登出,如下

1
2
3
4
5
6
@RequestMapping(path = "logout")
public String logout(HttpSession httpSession) {
// 注销当前的session
httpSession.invalidate();
return "登出成功";
}

4. session实现原理

SpringBoot提供了一套非常简单的session机制,那么它又是怎么工作的呢? 特别是它是怎么识别用户身份的呢? session又是存在什么地方的呢?

session:再浏览器窗口打开期间,这个会话一直有效,即先访问login,然后再访问time,可以直接拿到name, 若再此过程中,再次访问了login更新了name,那么访问time获取到的也是新的name

当浏览器关闭之后,重新再访问 time 接口,则此时将拿不到 name

核心工作原理:

  • 借助cookie中的 JESSIONID 来作为用户身份标识,这个数据相同的,认为是同一个用户;然后会将session再内存中存一份,有过期时间的限制,通常每次访问一次,过期时间重新刷新
  • 当浏览器不支持cookie时,借助url重写,将 sessionId 写道url的地址中,参数名 = jsessionid

从上面的描述中,就可以看出几个关键点:

  • session主要是存在内存中,根据用户请求的cookie来识别用户身份,且有一个过期时间 (那么问题来了,内存有大小限制么?会出现oom么?)
  • 对于用户而言,每次关闭浏览器再重新打开,会重新生成 JESSIONID 的cookies值,由于这个值的更改,导致后端无法记录之前访问的是谁

不能错过的源码和相关知识点

0. 项目

1. 微信公众号: 一灰灰Blog

尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

一灰灰blog


打赏 如果觉得我的文章对您有帮助,请随意打赏。
分享到